Commit ad1f2f59 authored by David Black's avatar David Black Committed by Commit Bot

Metalayer mode should not be sticky.

We need to disable it:
- when Assistant UI is dismissed.
- when an Assistant interaction is started (e.g. via hotword).

Bug: b:110961300
Change-Id: I97024e9f2681d171c40f54ac5b47c5ed549085b6
Reviewed-on: https://chromium-review.googlesource.com/1119530
Commit-Queue: David Black <dmblack@google.com>
Reviewed-by: default avatarXiaohui Chen <xiaohuic@chromium.org>
Reviewed-by: default avatarJames Cook <jamescook@chromium.org>
Cr-Commit-Position: refs/heads/master@{#573520}
parent 7c1bf775
...@@ -92,12 +92,27 @@ void AssistantInteractionController::OnHighlighterEnabledChanged( ...@@ -92,12 +92,27 @@ void AssistantInteractionController::OnHighlighterEnabledChanged(
break; break;
case HighlighterEnabledState::kDisabledByUser: case HighlighterEnabledState::kDisabledByUser:
FALLTHROUGH; FALLTHROUGH;
case HighlighterEnabledState::kDisabledBySessionEnd: case HighlighterEnabledState::kDisabledBySessionComplete:
assistant_interaction_model_.SetInputModality(InputModality::kKeyboard); assistant_interaction_model_.SetInputModality(InputModality::kKeyboard);
break; break;
case HighlighterEnabledState::kDisabledBySessionAbort:
// When metalayer mode has been aborted, no action necessary. Abort occurs
// as a result of an interaction starting, most likely due to hotword
// detection. Setting the input modality in these cases would have the
// unintended consequence of stopping the active interaction.
break;
} }
} }
void AssistantInteractionController::OnInteractionStateChanged(
InteractionState interaction_state) {
if (interaction_state != InteractionState::kActive)
return;
// Metalayer mode should not be sticky. Disable it on interaction start.
Shell::Get()->highlighter_controller()->AbortSession();
}
void AssistantInteractionController::OnInputModalityChanged( void AssistantInteractionController::OnInputModalityChanged(
InputModality input_modality) { InputModality input_modality) {
if (input_modality == InputModality::kVoice) if (input_modality == InputModality::kVoice)
......
...@@ -61,6 +61,7 @@ class AssistantInteractionController ...@@ -61,6 +61,7 @@ class AssistantInteractionController
void OnSuggestionChipPressed(int id); void OnSuggestionChipPressed(int id);
// AssistantInteractionModelObserver: // AssistantInteractionModelObserver:
void OnInteractionStateChanged(InteractionState interaction_state) override;
void OnInputModalityChanged(InputModality input_modality) override; void OnInputModalityChanged(InputModality input_modality) override;
void OnCommittedQueryChanged(const AssistantQuery& committed_query) override; void OnCommittedQueryChanged(const AssistantQuery& committed_query) override;
......
...@@ -41,6 +41,7 @@ void ShowToast(const std::string& id, int message_id) { ...@@ -41,6 +41,7 @@ void ShowToast(const std::string& id, int message_id) {
AssistantUiController::AssistantUiController( AssistantUiController::AssistantUiController(
AssistantController* assistant_controller) AssistantController* assistant_controller)
: assistant_controller_(assistant_controller) { : assistant_controller_(assistant_controller) {
AddModelObserver(this);
assistant_controller_->AddObserver(this); assistant_controller_->AddObserver(this);
Shell::Get()->highlighter_controller()->AddObserver(this); Shell::Get()->highlighter_controller()->AddObserver(this);
} }
...@@ -48,6 +49,7 @@ AssistantUiController::AssistantUiController( ...@@ -48,6 +49,7 @@ AssistantUiController::AssistantUiController(
AssistantUiController::~AssistantUiController() { AssistantUiController::~AssistantUiController() {
Shell::Get()->highlighter_controller()->RemoveObserver(this); Shell::Get()->highlighter_controller()->RemoveObserver(this);
assistant_controller_->RemoveObserver(this); assistant_controller_->RemoveObserver(this);
RemoveModelObserver(this);
if (container_view_) if (container_view_)
container_view_->GetWidget()->RemoveObserver(this); container_view_->GetWidget()->RemoveObserver(this);
...@@ -158,7 +160,8 @@ void AssistantUiController::OnHighlighterEnabledChanged( ...@@ -158,7 +160,8 @@ void AssistantUiController::OnHighlighterEnabledChanged(
if (assistant_ui_model_.visible()) if (assistant_ui_model_.visible())
HideUi(AssistantSource::kStylus); HideUi(AssistantSource::kStylus);
break; break;
case HighlighterEnabledState::kDisabledBySessionEnd: case HighlighterEnabledState::kDisabledBySessionComplete:
case HighlighterEnabledState::kDisabledBySessionAbort:
// No action necessary. // No action necessary.
break; break;
} }
...@@ -177,6 +180,15 @@ void AssistantUiController::OnUrlOpened(const GURL& url) { ...@@ -177,6 +180,15 @@ void AssistantUiController::OnUrlOpened(const GURL& url) {
HideUi(AssistantSource::kUnspecified); HideUi(AssistantSource::kUnspecified);
} }
void AssistantUiController::OnUiVisibilityChanged(bool visible,
AssistantSource source) {
if (visible)
return;
// Metalayer mode should not be sticky. Disable it when hiding UI.
Shell::Get()->highlighter_controller()->AbortSession();
}
void AssistantUiController::ShowUi(AssistantSource source) { void AssistantUiController::ShowUi(AssistantSource source) {
if (!Shell::Get()->voice_interaction_controller()->setup_completed()) { if (!Shell::Get()->voice_interaction_controller()->setup_completed()) {
assistant_setup_->StartAssistantOptInFlow(); assistant_setup_->StartAssistantOptInFlow();
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "ash/assistant/assistant_controller_observer.h" #include "ash/assistant/assistant_controller_observer.h"
#include "ash/assistant/model/assistant_interaction_model_observer.h" #include "ash/assistant/model/assistant_interaction_model_observer.h"
#include "ash/assistant/model/assistant_ui_model.h" #include "ash/assistant/model/assistant_ui_model.h"
#include "ash/assistant/model/assistant_ui_model_observer.h"
#include "ash/assistant/ui/caption_bar.h" #include "ash/assistant/ui/caption_bar.h"
#include "ash/assistant/ui/dialog_plate/dialog_plate.h" #include "ash/assistant/ui/dialog_plate/dialog_plate.h"
#include "ash/highlighter/highlighter_controller.h" #include "ash/highlighter/highlighter_controller.h"
...@@ -41,6 +42,7 @@ class ASH_EXPORT AssistantUiController ...@@ -41,6 +42,7 @@ class ASH_EXPORT AssistantUiController
: public views::WidgetObserver, : public views::WidgetObserver,
public AssistantControllerObserver, public AssistantControllerObserver,
public AssistantInteractionModelObserver, public AssistantInteractionModelObserver,
public AssistantUiModelObserver,
public CaptionBarDelegate, public CaptionBarDelegate,
public DialogPlateObserver, public DialogPlateObserver,
public HighlighterController::Observer { public HighlighterController::Observer {
...@@ -89,6 +91,9 @@ class ASH_EXPORT AssistantUiController ...@@ -89,6 +91,9 @@ class ASH_EXPORT AssistantUiController
void OnDeepLinkReceived(const GURL& deep_link) override; void OnDeepLinkReceived(const GURL& deep_link) override;
void OnUrlOpened(const GURL& url) override; void OnUrlOpened(const GURL& url) override;
// AssistantUiModelObserver:
void OnUiVisibilityChanged(bool visible, AssistantSource source) override;
void ShowUi(AssistantSource source); void ShowUi(AssistantSource source);
void HideUi(AssistantSource source); void HideUi(AssistantSource source);
void ToggleUi(AssistantSource source); void ToggleUi(AssistantSource source);
......
...@@ -91,6 +91,11 @@ void HighlighterController::UpdateEnabledState( ...@@ -91,6 +91,11 @@ void HighlighterController::UpdateEnabledState(
observer.OnHighlighterEnabledChanged(enabled_state); observer.OnHighlighterEnabledChanged(enabled_state);
} }
void HighlighterController::AbortSession() {
if (enabled_state_ == HighlighterEnabledState::kEnabled)
UpdateEnabledState(HighlighterEnabledState::kDisabledBySessionAbort);
}
void HighlighterController::BindRequest( void HighlighterController::BindRequest(
mojom::HighlighterControllerRequest request) { mojom::HighlighterControllerRequest request) {
binding_.Bind(std::move(request)); binding_.Bind(std::move(request));
......
...@@ -31,8 +31,11 @@ enum class HighlighterEnabledState { ...@@ -31,8 +31,11 @@ enum class HighlighterEnabledState {
// Highlighter is disabled by user directly, for example disabling palette // Highlighter is disabled by user directly, for example disabling palette
// tool by user actions on palette menu. // tool by user actions on palette menu.
kDisabledByUser, kDisabledByUser,
// Highlighter is disabled on metalayer session aborted or complete. // Highlighter is disabled on metalayer session complete.
kDisabledBySessionEnd, kDisabledBySessionComplete,
// Highlighter is disabled on metalayer session abort. An abort may occur due
// to dismissal of Assistant UI or due to interruption by user via hotword.
kDisabledBySessionAbort,
}; };
// Controller for the highlighter functionality. // Controller for the highlighter functionality.
...@@ -72,6 +75,10 @@ class ASH_EXPORT HighlighterController ...@@ -72,6 +75,10 @@ class ASH_EXPORT HighlighterController
// Update highlighter enabled |state| and notify observers. // Update highlighter enabled |state| and notify observers.
void UpdateEnabledState(HighlighterEnabledState enabled_state); void UpdateEnabledState(HighlighterEnabledState enabled_state);
// Aborts the current metalayer session. If no metalayer session exists,
// calling this method is a no-op.
void AbortSession();
void BindRequest(mojom::HighlighterControllerRequest request); void BindRequest(mojom::HighlighterControllerRequest request);
// mojom::HighlighterController: // mojom::HighlighterController:
......
...@@ -29,13 +29,19 @@ class TestHighlighterObserver : public HighlighterController::Observer { ...@@ -29,13 +29,19 @@ class TestHighlighterObserver : public HighlighterController::Observer {
// HighlighterController::Observer: // HighlighterController::Observer:
void OnHighlighterEnabledChanged(HighlighterEnabledState state) override { void OnHighlighterEnabledChanged(HighlighterEnabledState state) override {
if (state == HighlighterEnabledState::kEnabled) { switch (state) {
++enabled_count_; case HighlighterEnabledState::kEnabled:
} else if (state == HighlighterEnabledState::kDisabledByUser) { ++enabled_count_;
++disabled_by_user_count_; break;
} else { case HighlighterEnabledState::kDisabledByUser:
DCHECK_EQ(HighlighterEnabledState::kDisabledBySessionEnd, state); ++disabled_by_user_count_;
++disabled_by_session_end_; break;
case HighlighterEnabledState::kDisabledBySessionAbort:
++disabled_by_session_abort_;
break;
case HighlighterEnabledState::kDisabledBySessionComplete:
++disabled_by_session_complete_;
break;
} }
} }
...@@ -45,7 +51,8 @@ class TestHighlighterObserver : public HighlighterController::Observer { ...@@ -45,7 +51,8 @@ class TestHighlighterObserver : public HighlighterController::Observer {
int enabled_count_ = 0; int enabled_count_ = 0;
int disabled_by_user_count_ = 0; int disabled_by_user_count_ = 0;
int disabled_by_session_end_ = 0; int disabled_by_session_abort_ = 0;
int disabled_by_session_complete_ = 0;
gfx::Rect last_recognized_rect_; gfx::Rect last_recognized_rect_;
private: private:
...@@ -529,30 +536,121 @@ TEST_F(HighlighterControllerTest, UpdateEnabledState) { ...@@ -529,30 +536,121 @@ TEST_F(HighlighterControllerTest, UpdateEnabledState) {
TestHighlighterObserver observer; TestHighlighterObserver observer;
controller_->AddObserver(&observer); controller_->AddObserver(&observer);
// Assert initial state.
ASSERT_EQ(0, observer.enabled_count_); ASSERT_EQ(0, observer.enabled_count_);
ASSERT_EQ(0, observer.disabled_by_user_count_); ASSERT_EQ(0, observer.disabled_by_user_count_);
ASSERT_EQ(0, observer.disabled_by_session_end_); ASSERT_EQ(0, observer.disabled_by_session_abort_);
ASSERT_EQ(0, observer.disabled_by_session_complete_);
// Test enabling.
tool_->OnEnable(); tool_->OnEnable();
EXPECT_EQ(1, observer.enabled_count_); EXPECT_EQ(1, observer.enabled_count_);
EXPECT_EQ(0, observer.disabled_by_user_count_); EXPECT_EQ(0, observer.disabled_by_user_count_);
EXPECT_EQ(0, observer.disabled_by_session_end_); EXPECT_EQ(0, observer.disabled_by_session_abort_);
EXPECT_EQ(0, observer.disabled_by_session_complete_);
// Test disabling by user.
tool_->OnDisable(); tool_->OnDisable();
EXPECT_EQ(1, observer.enabled_count_); EXPECT_EQ(1, observer.enabled_count_);
EXPECT_EQ(1, observer.disabled_by_user_count_); EXPECT_EQ(1, observer.disabled_by_user_count_);
EXPECT_EQ(0, observer.disabled_by_session_end_); EXPECT_EQ(0, observer.disabled_by_session_abort_);
EXPECT_EQ(0, observer.disabled_by_session_complete_);
// Test disabling by session abort.
tool_->OnEnable(); tool_->OnEnable();
EXPECT_EQ(2, observer.enabled_count_); EXPECT_EQ(2, observer.enabled_count_);
EXPECT_EQ(1, observer.disabled_by_user_count_); EXPECT_EQ(1, observer.disabled_by_user_count_);
EXPECT_EQ(0, observer.disabled_by_session_end_); EXPECT_EQ(0, observer.disabled_by_session_abort_);
EXPECT_EQ(0, observer.disabled_by_session_complete_);
controller_->UpdateEnabledState( controller_->UpdateEnabledState(
HighlighterEnabledState::kDisabledBySessionEnd); HighlighterEnabledState::kDisabledBySessionAbort);
EXPECT_EQ(2, observer.enabled_count_); EXPECT_EQ(2, observer.enabled_count_);
EXPECT_EQ(1, observer.disabled_by_user_count_); EXPECT_EQ(1, observer.disabled_by_user_count_);
EXPECT_EQ(1, observer.disabled_by_session_end_); EXPECT_EQ(1, observer.disabled_by_session_abort_);
EXPECT_EQ(0, observer.disabled_by_session_complete_);
// Test disabling by session complete.
tool_->OnEnable();
EXPECT_EQ(3, observer.enabled_count_);
EXPECT_EQ(1, observer.disabled_by_user_count_);
EXPECT_EQ(1, observer.disabled_by_session_abort_);
EXPECT_EQ(0, observer.disabled_by_session_complete_);
controller_->UpdateEnabledState(
HighlighterEnabledState::kDisabledBySessionComplete);
EXPECT_EQ(3, observer.enabled_count_);
EXPECT_EQ(1, observer.disabled_by_user_count_);
EXPECT_EQ(1, observer.disabled_by_session_abort_);
EXPECT_EQ(1, observer.disabled_by_session_complete_);
controller_->RemoveObserver(&observer); controller_->RemoveObserver(&observer);
} }
// Test aborting a metalayer session and notifying observers properly.
TEST_F(HighlighterControllerTest, AbortSession) {
TestHighlighterObserver observer;
controller_->AddObserver(&observer);
// Assert initial state.
ASSERT_EQ(0, observer.enabled_count_);
ASSERT_EQ(0, observer.disabled_by_user_count_);
ASSERT_EQ(0, observer.disabled_by_session_abort_);
ASSERT_EQ(0, observer.disabled_by_session_complete_);
// Start metalayer session.
tool_->OnEnable();
EXPECT_EQ(1, observer.enabled_count_);
EXPECT_EQ(0, observer.disabled_by_user_count_);
EXPECT_EQ(0, observer.disabled_by_session_abort_);
EXPECT_EQ(0, observer.disabled_by_session_complete_);
// Abort metalayer session.
controller_->AbortSession();
EXPECT_EQ(1, observer.enabled_count_);
EXPECT_EQ(0, observer.disabled_by_user_count_);
EXPECT_EQ(1, observer.disabled_by_session_abort_);
EXPECT_EQ(0, observer.disabled_by_session_complete_);
// Assert no-op when aborting an aborted session.
controller_->AbortSession();
EXPECT_EQ(1, observer.enabled_count_);
EXPECT_EQ(0, observer.disabled_by_user_count_);
EXPECT_EQ(1, observer.disabled_by_session_abort_);
EXPECT_EQ(0, observer.disabled_by_session_complete_);
// Assert no-op when aborting a completed session.
tool_->OnEnable();
EXPECT_EQ(2, observer.enabled_count_);
EXPECT_EQ(0, observer.disabled_by_user_count_);
EXPECT_EQ(1, observer.disabled_by_session_abort_);
EXPECT_EQ(0, observer.disabled_by_session_complete_);
controller_->UpdateEnabledState(
HighlighterEnabledState::kDisabledBySessionComplete);
EXPECT_EQ(2, observer.enabled_count_);
EXPECT_EQ(0, observer.disabled_by_user_count_);
EXPECT_EQ(1, observer.disabled_by_session_abort_);
EXPECT_EQ(1, observer.disabled_by_session_complete_);
controller_->AbortSession();
EXPECT_EQ(2, observer.enabled_count_);
EXPECT_EQ(0, observer.disabled_by_user_count_);
EXPECT_EQ(1, observer.disabled_by_session_abort_);
EXPECT_EQ(1, observer.disabled_by_session_complete_);
// Assert no-op when aborting a disabled session.
tool_->OnEnable();
EXPECT_EQ(3, observer.enabled_count_);
EXPECT_EQ(0, observer.disabled_by_user_count_);
EXPECT_EQ(1, observer.disabled_by_session_abort_);
EXPECT_EQ(1, observer.disabled_by_session_complete_);
tool_->OnDisable();
EXPECT_EQ(3, observer.enabled_count_);
EXPECT_EQ(1, observer.disabled_by_user_count_);
EXPECT_EQ(1, observer.disabled_by_session_abort_);
EXPECT_EQ(1, observer.disabled_by_session_complete_);
controller_->AbortSession();
EXPECT_EQ(3, observer.enabled_count_);
EXPECT_EQ(1, observer.disabled_by_user_count_);
EXPECT_EQ(1, observer.disabled_by_session_abort_);
EXPECT_EQ(1, observer.disabled_by_session_complete_);
}
} // namespace ash } // namespace ash
...@@ -224,7 +224,7 @@ void MetalayerMode::UpdateView() { ...@@ -224,7 +224,7 @@ void MetalayerMode::UpdateView() {
void MetalayerMode::OnMetalayerSessionComplete() { void MetalayerMode::OnMetalayerSessionComplete() {
Shell::Get()->highlighter_controller()->UpdateEnabledState( Shell::Get()->highlighter_controller()->UpdateEnabledState(
HighlighterEnabledState::kDisabledBySessionEnd); HighlighterEnabledState::kDisabledBySessionComplete);
} }
} // namespace ash } // namespace ash
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