Commit 0999c8d5 authored by Xiaohui Chen's avatar Xiaohui Chen Committed by Commit Bot

assistant: fix history not working with first key press

Test: unittests and local test
Bug: b:139438276
Change-Id: Ia17fe0126a7f400553e0954ffc471629b4884fa6
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1935153
Commit-Queue: Xiaohui Chen <xiaohuic@chromium.org>
Reviewed-by: default avatarXiyuan Xia <xiyuan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#719437}
parent 0b6ccac1
...@@ -313,6 +313,10 @@ void AppListPresenterDelegateImpl::OnKeyEvent(ui::KeyEvent* event) { ...@@ -313,6 +313,10 @@ void AppListPresenterDelegateImpl::OnKeyEvent(ui::KeyEvent* event) {
if (view_->search_box_view()->is_search_box_active()) if (view_->search_box_view()->is_search_box_active())
return; return;
// Don't absorb the first event when showing Assistant.
if (view_->IsShowingEmbeddedAssistantUI())
return;
// Arrow keys or Tab will engage the traversal mode. // Arrow keys or Tab will engage the traversal mode.
if ((IsUnhandledArrowKeyEvent(*event) || event->key_code() == ui::VKEY_TAB)) { if ((IsUnhandledArrowKeyEvent(*event) || event->key_code() == ui::VKEY_TAB)) {
// Handle the first arrow key event to just show the focus rings. // Handle the first arrow key event to just show the focus rings.
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include "ash/app_list/views/app_list_view.h" #include "ash/app_list/views/app_list_view.h"
#include <algorithm> #include <algorithm>
#include <string>
#include <utility> #include <utility>
#include <vector> #include <vector>
...@@ -839,6 +840,10 @@ SkColor AppListView::GetAppListBackgroundShieldColorForTest() { ...@@ -839,6 +840,10 @@ SkColor AppListView::GetAppListBackgroundShieldColorForTest() {
return app_list_background_shield_->GetColorForTest(); return app_list_background_shield_->GetColorForTest();
} }
bool AppListView::IsShowingEmbeddedAssistantUI() const {
return app_list_main_view()->contents_view()->IsShowingEmbeddedAssistantUI();
}
void AppListView::UpdateAppListConfig(aura::Window* parent_window) { void AppListView::UpdateAppListConfig(aura::Window* parent_window) {
// For side shelf, extra horizontal margin is needed to ensure the apps grid // For side shelf, extra horizontal margin is needed to ensure the apps grid
// does not overlap with shelf. // does not overlap with shelf.
...@@ -2247,10 +2252,6 @@ bool AppListView::ShouldIgnoreScrollEvents() { ...@@ -2247,10 +2252,6 @@ bool AppListView::ShouldIgnoreScrollEvents() {
GetRootAppsGridView()->pagination_model()->has_transition(); GetRootAppsGridView()->pagination_model()->has_transition();
} }
bool AppListView::IsShowingEmbeddedAssistantUI() const {
return app_list_main_view()->contents_view()->IsShowingEmbeddedAssistantUI();
}
int AppListView::GetPreferredWidgetYForState( int AppListView::GetPreferredWidgetYForState(
ash::AppListViewState state) const { ash::AppListViewState state) const {
// Note that app list container fills the screen, so we can treat the // Note that app list container fills the screen, so we can treat the
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#define ASH_APP_LIST_VIEWS_APP_LIST_VIEW_H_ #define ASH_APP_LIST_VIEWS_APP_LIST_VIEW_H_
#include <memory> #include <memory>
#include <string>
#include <vector> #include <vector>
#include "ash/app_list/app_list_export.h" #include "ash/app_list/app_list_export.h"
...@@ -55,14 +56,10 @@ FORWARD_DECLARE_TEST(AppListControllerImplTest, ...@@ -55,14 +56,10 @@ FORWARD_DECLARE_TEST(AppListControllerImplTest,
FORWARD_DECLARE_TEST(AppListControllerImplMetricsTest, FORWARD_DECLARE_TEST(AppListControllerImplMetricsTest,
PresentationTimeRecordedForDragInTabletMode); PresentationTimeRecordedForDragInTabletMode);
namespace {
// The fraction of app list height that the app list must be released at in // The fraction of app list height that the app list must be released at in
// order to transition to the next state. // order to transition to the next state.
constexpr int kAppListThresholdDenominator = 3; constexpr int kAppListThresholdDenominator = 3;
} // namespace
// AppListView is the top-level view and controller of app list UI. It creates // AppListView is the top-level view and controller of app list UI. It creates
// and hosts a AppsGridView and passes AppListModel to it for display. // and hosts a AppsGridView and passes AppListModel to it for display.
// TODO(newcomer|weidongg): Organize the cc file to match the order of // TODO(newcomer|weidongg): Organize the cc file to match the order of
...@@ -367,6 +364,9 @@ class APP_LIST_EXPORT AppListView : public views::WidgetDelegateView, ...@@ -367,6 +364,9 @@ class APP_LIST_EXPORT AppListView : public views::WidgetDelegateView,
SkColor GetAppListBackgroundShieldColorForTest(); SkColor GetAppListBackgroundShieldColorForTest();
// Returns true if the Embedded Assistant UI is currently being shown.
bool IsShowingEmbeddedAssistantUI() const;
private: private:
FRIEND_TEST_ALL_PREFIXES(ash::AppListControllerImplTest, FRIEND_TEST_ALL_PREFIXES(ash::AppListControllerImplTest,
CheckAppListViewBoundsWhenVKeyboardEnabled); CheckAppListViewBoundsWhenVKeyboardEnabled);
...@@ -471,9 +471,6 @@ class APP_LIST_EXPORT AppListView : public views::WidgetDelegateView, ...@@ -471,9 +471,6 @@ class APP_LIST_EXPORT AppListView : public views::WidgetDelegateView,
// Returns true if scroll events should be ignored. // Returns true if scroll events should be ignored.
bool ShouldIgnoreScrollEvents(); bool ShouldIgnoreScrollEvents();
// Returns true if the Embedded Assistant UI is currently being shown.
bool IsShowingEmbeddedAssistantUI() const;
// Returns preferred y of fullscreen widget bounds in parent window for the // Returns preferred y of fullscreen widget bounds in parent window for the
// specified state. // specified state.
int GetPreferredWidgetYForState(ash::AppListViewState state) const; int GetPreferredWidgetYForState(ash::AppListViewState state) const;
......
...@@ -258,6 +258,33 @@ TEST_F(AssistantPageViewTest, ...@@ -258,6 +258,33 @@ TEST_F(AssistantPageViewTest,
EXPECT_HAS_FOCUS(input_text_field()); EXPECT_HAS_FOCUS(input_text_field());
} }
TEST_F(AssistantPageViewTest, RememberAndShowHistory) {
ShowAssistantUiInTextMode();
EXPECT_HAS_FOCUS(input_text_field());
MockAssistantInteractionWithQueryAndResponse("query 1", "response 1");
MockAssistantInteractionWithQueryAndResponse("query 2", "response 2");
EXPECT_HAS_FOCUS(input_text_field());
EXPECT_TRUE(input_text_field()->GetText().empty());
GetEventGenerator()->PressKey(ui::KeyboardCode::VKEY_UP, /*flags=*/0);
EXPECT_EQ(input_text_field()->GetText(), base::UTF8ToUTF16("query 2"));
GetEventGenerator()->PressKey(ui::KeyboardCode::VKEY_UP, /*flags=*/0);
EXPECT_EQ(input_text_field()->GetText(), base::UTF8ToUTF16("query 1"));
GetEventGenerator()->PressKey(ui::KeyboardCode::VKEY_UP, /*flags=*/0);
EXPECT_EQ(input_text_field()->GetText(), base::UTF8ToUTF16("query 1"));
GetEventGenerator()->PressKey(ui::KeyboardCode::VKEY_DOWN, /*flags=*/0);
EXPECT_EQ(input_text_field()->GetText(), base::UTF8ToUTF16("query 2"));
GetEventGenerator()->PressKey(ui::KeyboardCode::VKEY_DOWN, /*flags=*/0);
EXPECT_TRUE(input_text_field()->GetText().empty());
}
// Tests the |AssistantPageView| with tablet mode enabled. // Tests the |AssistantPageView| with tablet mode enabled.
class AssistantPageViewTabletModeTest : public AssistantAshTestBase { class AssistantPageViewTabletModeTest : public AssistantAshTestBase {
public: public:
......
...@@ -4,6 +4,9 @@ ...@@ -4,6 +4,9 @@
#include "ash/assistant/test/assistant_ash_test_base.h" #include "ash/assistant/test/assistant_ash_test_base.h"
#include <string>
#include <utility>
#include "ash/app_list/app_list_controller_impl.h" #include "ash/app_list/app_list_controller_impl.h"
#include "ash/app_list/views/assistant/assistant_main_view.h" #include "ash/app_list/views/assistant/assistant_main_view.h"
#include "ash/app_list/views/assistant/assistant_page_view.h" #include "ash/app_list/views/assistant/assistant_page_view.h"
...@@ -133,14 +136,18 @@ views::View* AssistantAshTestBase::page_view() { ...@@ -133,14 +136,18 @@ views::View* AssistantAshTestBase::page_view() {
void AssistantAshTestBase::MockAssistantInteractionWithResponse( void AssistantAshTestBase::MockAssistantInteractionWithResponse(
const std::string& response_text) { const std::string& response_text) {
const std::string query = std::string("input text"); MockAssistantInteractionWithQueryAndResponse(/*query=*/"input text",
response_text);
}
void AssistantAshTestBase::MockAssistantInteractionWithQueryAndResponse(
const std::string& query,
const std::string& response_text) {
SendQueryThroughTextField(query); SendQueryThroughTextField(query);
assistant_service()->SetInteractionResponse( auto response = std::make_unique<InteractionResponse>();
InteractionResponse() response->AddTextResponse(response_text)
.AddTextResponse(response_text) ->AddResolution(InteractionResponse::Resolution::kNormal);
.AddResolution(InteractionResponse::Resolution::kNormal) assistant_service()->SetInteractionResponse(std::move(response));
.Clone());
base::RunLoop().RunUntilIdle(); base::RunLoop().RunUntilIdle();
} }
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#define ASH_ASSISTANT_TEST_ASSISTANT_ASH_TEST_BASE_H_ #define ASH_ASSISTANT_TEST_ASSISTANT_ASH_TEST_BASE_H_
#include <memory> #include <memory>
#include <string>
#include <vector> #include <vector>
#include "ash/assistant/model/assistant_ui_model.h" #include "ash/assistant/model/assistant_ui_model.h"
...@@ -64,6 +65,10 @@ class AssistantAshTestBase : public AshTestBase { ...@@ -64,6 +65,10 @@ class AssistantAshTestBase : public AshTestBase {
// and receiving |response_text| as a response to display. // and receiving |response_text| as a response to display.
void MockAssistantInteractionWithResponse(const std::string& response_text); void MockAssistantInteractionWithResponse(const std::string& response_text);
void MockAssistantInteractionWithQueryAndResponse(
const std::string& query,
const std::string& response_text);
// Simulate the user entering a query followed by <return>. // Simulate the user entering a query followed by <return>.
void SendQueryThroughTextField(const std::string& query); void SendQueryThroughTextField(const std::string& query);
......
...@@ -4,7 +4,9 @@ ...@@ -4,7 +4,9 @@
#include "ash/assistant/test/test_assistant_service.h" #include "ash/assistant/test/test_assistant_service.h"
#include <memory>
#include <utility> #include <utility>
#include <vector>
#include "ash/assistant/assistant_interaction_controller.h" #include "ash/assistant/assistant_interaction_controller.h"
#include "chromeos/services/assistant/public/mojom/assistant.mojom.h" #include "chromeos/services/assistant/public/mojom/assistant.mojom.h"
...@@ -170,21 +172,15 @@ class InteractionResponse::Response { ...@@ -170,21 +172,15 @@ class InteractionResponse::Response {
Response() = default; Response() = default;
virtual ~Response() = default; virtual ~Response() = default;
virtual std::unique_ptr<Response> Clone() const = 0;
virtual void SendTo( virtual void SendTo(
chromeos::assistant::mojom::AssistantInteractionSubscriber* receiver) = 0; chromeos::assistant::mojom::AssistantInteractionSubscriber* receiver) = 0;
}; };
class TextResponse : public InteractionResponse::Response { class TextResponse : public InteractionResponse::Response {
public: public:
TextResponse(const std::string& text) : text_(text) {} explicit TextResponse(const std::string& text) : text_(text) {}
~TextResponse() override = default; ~TextResponse() override = default;
std::unique_ptr<Response> Clone() const override {
return std::make_unique<TextResponse>(text_);
}
void SendTo(chromeos::assistant::mojom::AssistantInteractionSubscriber* void SendTo(chromeos::assistant::mojom::AssistantInteractionSubscriber*
receiver) override { receiver) override {
receiver->OnTextResponse(text_); receiver->OnTextResponse(text_);
...@@ -200,13 +196,10 @@ class ResolutionResponse : public InteractionResponse::Response { ...@@ -200,13 +196,10 @@ class ResolutionResponse : public InteractionResponse::Response {
public: public:
using Resolution = InteractionResponse::Resolution; using Resolution = InteractionResponse::Resolution;
ResolutionResponse(Resolution resolution) : resolution_(resolution) {} explicit ResolutionResponse(Resolution resolution)
: resolution_(resolution) {}
~ResolutionResponse() override = default; ~ResolutionResponse() override = default;
std::unique_ptr<Response> Clone() const override {
return std::make_unique<ResolutionResponse>(resolution_);
}
void SendTo(chromeos::assistant::mojom::AssistantInteractionSubscriber* void SendTo(chromeos::assistant::mojom::AssistantInteractionSubscriber*
receiver) override { receiver) override {
receiver->OnInteractionFinished(resolution_); receiver->OnInteractionFinished(resolution_);
...@@ -236,7 +229,7 @@ TestAssistantService::CreateRemoteAndBind() { ...@@ -236,7 +229,7 @@ TestAssistantService::CreateRemoteAndBind() {
} }
void TestAssistantService::SetInteractionResponse( void TestAssistantService::SetInteractionResponse(
InteractionResponse&& response) { std::unique_ptr<InteractionResponse> response) {
interaction_response_ = std::move(response); interaction_response_ = std::move(response);
} }
...@@ -263,12 +256,14 @@ void TestAssistantService ::StartTextInteraction( ...@@ -263,12 +256,14 @@ void TestAssistantService ::StartTextInteraction(
chromeos::assistant::mojom::AssistantQuerySource source, chromeos::assistant::mojom::AssistantQuerySource source,
bool allow_tts) { bool allow_tts) {
StartInteraction(AssistantInteractionType::kText, source, query); StartInteraction(AssistantInteractionType::kText, source, query);
SendInteractionResponse(); if (interaction_response_)
SendInteractionResponse();
} }
void TestAssistantService ::StartVoiceInteraction() { void TestAssistantService ::StartVoiceInteraction() {
StartInteraction(AssistantInteractionType::kVoice); StartInteraction(AssistantInteractionType::kVoice);
SendInteractionResponse(); if (interaction_response_)
SendInteractionResponse();
} }
void TestAssistantService ::StartWarmerWelcomeInteraction( void TestAssistantService ::StartWarmerWelcomeInteraction(
...@@ -278,6 +273,10 @@ void TestAssistantService ::StartWarmerWelcomeInteraction( ...@@ -278,6 +273,10 @@ void TestAssistantService ::StartWarmerWelcomeInteraction(
} }
void TestAssistantService ::StopActiveInteraction(bool cancel_conversation) { void TestAssistantService ::StopActiveInteraction(bool cancel_conversation) {
if (!running_active_interaction_)
return;
running_active_interaction_ = false;
for (auto& subscriber : interaction_subscribers_) { for (auto& subscriber : interaction_subscribers_) {
subscriber->OnInteractionFinished( subscriber->OnInteractionFinished(
AssistantInteractionResolution::kInterruption); AssistantInteractionResolution::kInterruption);
...@@ -328,44 +327,36 @@ void TestAssistantService::StartInteraction( ...@@ -328,44 +327,36 @@ void TestAssistantService::StartInteraction(
chromeos::assistant::mojom::AssistantInteractionType type, chromeos::assistant::mojom::AssistantInteractionType type,
chromeos::assistant::mojom::AssistantQuerySource source, chromeos::assistant::mojom::AssistantQuerySource source,
const std::string& query) { const std::string& query) {
DCHECK(!running_active_interaction_);
for (auto& subscriber : interaction_subscribers_) { for (auto& subscriber : interaction_subscribers_) {
subscriber->OnInteractionStarted( subscriber->OnInteractionStarted(
AssistantInteractionMetadata::New(type, source, query)); AssistantInteractionMetadata::New(type, source, query));
} }
running_active_interaction_ = true;
} }
void TestAssistantService::SendInteractionResponse() { void TestAssistantService::SendInteractionResponse() {
InteractionResponse response = PopInteractionResponse(); DCHECK(interaction_response_);
DCHECK(running_active_interaction_);
for (auto& subscriber : interaction_subscribers_) for (auto& subscriber : interaction_subscribers_)
response.SendTo(subscriber.get()); interaction_response_->SendTo(subscriber.get());
} DCHECK(!current_interaction());
interaction_response_.reset();
InteractionResponse TestAssistantService::PopInteractionResponse() { running_active_interaction_ = false;
return std::move(interaction_response_);
} }
InteractionResponse::InteractionResponse() = default; InteractionResponse::InteractionResponse() = default;
InteractionResponse::InteractionResponse(InteractionResponse&& other) = default;
InteractionResponse& InteractionResponse::operator=(
InteractionResponse&& other) = default;
InteractionResponse::~InteractionResponse() = default; InteractionResponse::~InteractionResponse() = default;
InteractionResponse InteractionResponse::Clone() const { InteractionResponse* InteractionResponse::AddTextResponse(
InteractionResponse result{};
for (const auto& response : responses_)
result.AddResponse(response->Clone());
return result;
}
InteractionResponse& InteractionResponse::AddTextResponse(
const std::string& text) { const std::string& text) {
AddResponse(std::make_unique<TextResponse>(text)); AddResponse(std::make_unique<TextResponse>(text));
return *this; return this;
} }
InteractionResponse& InteractionResponse::AddResolution(Resolution resolution) { InteractionResponse* InteractionResponse::AddResolution(Resolution resolution) {
AddResponse(std::make_unique<ResolutionResponse>(resolution)); AddResponse(std::make_unique<ResolutionResponse>(resolution));
return *this; return this;
} }
void InteractionResponse::AddResponse(std::unique_ptr<Response> response) { void InteractionResponse::AddResponse(std::unique_ptr<Response> response) {
......
...@@ -5,7 +5,9 @@ ...@@ -5,7 +5,9 @@
#ifndef ASH_ASSISTANT_TEST_TEST_ASSISTANT_SERVICE_H_ #ifndef ASH_ASSISTANT_TEST_TEST_ASSISTANT_SERVICE_H_
#define ASH_ASSISTANT_TEST_TEST_ASSISTANT_SERVICE_H_ #define ASH_ASSISTANT_TEST_TEST_ASSISTANT_SERVICE_H_
#include <memory>
#include <string> #include <string>
#include <vector>
#include "base/macros.h" #include "base/macros.h"
#include "base/timer/timer.h" #include "base/timer/timer.h"
...@@ -24,28 +26,23 @@ class SanityCheckSubscriber; ...@@ -24,28 +26,23 @@ class SanityCheckSubscriber;
// chain calls to the provided |AddXYZ| methods. // chain calls to the provided |AddXYZ| methods.
// //
// Example usage: // Example usage:
// assistant_service()->SetInteractionResponse( // auto response = std::make_unique<InteractionResponse>();
// InteractionResponse() // response->AddTextResponse("The response text")
// .AddTextResponse("The response text") // ->AddResolution(InteractionResponse::Resolution::kNormal);
// .AddResolution(InteractionResponse::Resolution::kNormal) // assistant_service()->SetInteractionResponse(std::move(response));
// .Clone());
class InteractionResponse { class InteractionResponse {
public: public:
using Resolution = chromeos::assistant::mojom::AssistantInteractionResolution; using Resolution = chromeos::assistant::mojom::AssistantInteractionResolution;
class Response; class Response;
InteractionResponse(); InteractionResponse();
InteractionResponse(InteractionResponse&& other);
InteractionResponse& operator=(InteractionResponse&& other);
~InteractionResponse(); ~InteractionResponse();
InteractionResponse Clone() const;
// A simple textual response. // A simple textual response.
InteractionResponse& AddTextResponse(const std::string& text); InteractionResponse* AddTextResponse(const std::string& text);
// If used this will cause us to finish the interaction by passing the given // If used this will cause us to finish the interaction by passing the given
// |resolution| to |AssistantInteractionSubscriber::OnInteractionFinished|. // |resolution| to |AssistantInteractionSubscriber::OnInteractionFinished|.
InteractionResponse& AddResolution(Resolution resolution); InteractionResponse* AddResolution(Resolution resolution);
void SendTo( void SendTo(
chromeos::assistant::mojom::AssistantInteractionSubscriber* receiver); chromeos::assistant::mojom::AssistantInteractionSubscriber* receiver);
...@@ -78,7 +75,7 @@ class TestAssistantService : public chromeos::assistant::mojom::Assistant { ...@@ -78,7 +75,7 @@ class TestAssistantService : public chromeos::assistant::mojom::Assistant {
CreateRemoteAndBind(); CreateRemoteAndBind();
// Set the response that will be invoked when the next interaction starts. // Set the response that will be invoked when the next interaction starts.
void SetInteractionResponse(InteractionResponse&& response); void SetInteractionResponse(std::unique_ptr<InteractionResponse> response);
// Returns the current interaction. // Returns the current interaction.
base::Optional<chromeos::assistant::mojom::AssistantInteractionMetadata> base::Optional<chromeos::assistant::mojom::AssistantInteractionMetadata>
...@@ -120,14 +117,15 @@ class TestAssistantService : public chromeos::assistant::mojom::Assistant { ...@@ -120,14 +117,15 @@ class TestAssistantService : public chromeos::assistant::mojom::Assistant {
chromeos::assistant::mojom::AssistantQuerySource::kUnspecified, chromeos::assistant::mojom::AssistantQuerySource::kUnspecified,
const std::string& query = std::string()); const std::string& query = std::string());
void SendInteractionResponse(); void SendInteractionResponse();
InteractionResponse PopInteractionResponse();
mojo::Receiver<chromeos::assistant::mojom::Assistant> receiver_{this}; mojo::Receiver<chromeos::assistant::mojom::Assistant> receiver_{this};
mojo::RemoteSet<chromeos::assistant::mojom::AssistantInteractionSubscriber> mojo::RemoteSet<chromeos::assistant::mojom::AssistantInteractionSubscriber>
interaction_subscribers_; interaction_subscribers_;
std::unique_ptr<SanityCheckSubscriber> sanity_check_subscriber_; std::unique_ptr<SanityCheckSubscriber> sanity_check_subscriber_;
std::unique_ptr<CurrentInteractionSubscriber> current_interaction_subscriber_; std::unique_ptr<CurrentInteractionSubscriber> current_interaction_subscriber_;
InteractionResponse interaction_response_; std::unique_ptr<InteractionResponse> interaction_response_;
bool running_active_interaction_ = false;
DISALLOW_COPY_AND_ASSIGN(TestAssistantService); DISALLOW_COPY_AND_ASSIGN(TestAssistantService);
}; };
......
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