Commit 4703d7bd authored by David Black's avatar David Black Committed by Commit Bot

Inverts interaction and UI start logic.

Previously, an interaction was started and this triggered UI to show.
Now, the UI is shown/hidden as desired and, depending on the entry
point, this will start an interaction as necessary.

This is important because we have the need to launch Assistant UI
without an interaction. This will occur when linking into Assistant
Settings, Reminders, etc.

Unit tests to follow in b/77656544.

Bug: b:80542452
Change-Id: I6de066b3a9ed86590b1fc467b4baa36f02833c66
Reviewed-on: https://chromium-review.googlesource.com/1106597Reviewed-by: default avatarXiyuan Xia <xiyuan@chromium.org>
Reviewed-by: default avatarXiaohui Chen <xiaohuic@chromium.org>
Commit-Queue: David Black <dmblack@google.com>
Cr-Commit-Position: refs/heads/master@{#569465}
parent 6c26c230
...@@ -15,7 +15,8 @@ ...@@ -15,7 +15,8 @@
#include "ash/accessibility/accessibility_controller.h" #include "ash/accessibility/accessibility_controller.h"
#include "ash/app_list/app_list_controller_impl.h" #include "ash/app_list/app_list_controller_impl.h"
#include "ash/assistant/assistant_controller.h" #include "ash/assistant/assistant_controller.h"
#include "ash/assistant/assistant_interaction_controller.h" #include "ash/assistant/assistant_ui_controller.h"
#include "ash/assistant/model/assistant_ui_model.h"
#include "ash/debug.h" #include "ash/debug.h"
#include "ash/display/display_configuration_controller.h" #include "ash/display/display_configuration_controller.h"
#include "ash/display/display_move_window_util.h" #include "ash/display/display_move_window_util.h"
...@@ -672,10 +673,8 @@ void HandleToggleVoiceInteraction(const ui::Accelerator& accelerator) { ...@@ -672,10 +673,8 @@ void HandleToggleVoiceInteraction(const ui::Accelerator& accelerator) {
// TODO(dmblack): Remove. Enabling eligibility check bypass for development // TODO(dmblack): Remove. Enabling eligibility check bypass for development
// purposes only. We should otherwise respect the eligibility rules below. // purposes only. We should otherwise respect the eligibility rules below.
if (chromeos::switches::IsAssistantEnabled()) { if (chromeos::switches::IsAssistantEnabled()) {
Shell::Get() Shell::Get()->assistant_controller()->ui_controller()->ToggleUi(
->assistant_controller() AssistantSource::kHotkey);
->interaction_controller()
->ToggleInteraction();
return; return;
} }
...@@ -714,10 +713,8 @@ void HandleToggleVoiceInteraction(const ui::Accelerator& accelerator) { ...@@ -714,10 +713,8 @@ void HandleToggleVoiceInteraction(const ui::Accelerator& accelerator) {
if (!chromeos::switches::IsAssistantEnabled()) { if (!chromeos::switches::IsAssistantEnabled()) {
Shell::Get()->app_list_controller()->ToggleVoiceInteractionSession(); Shell::Get()->app_list_controller()->ToggleVoiceInteractionSession();
} else { } else {
Shell::Get() Shell::Get()->assistant_controller()->ui_controller()->ToggleUi(
->assistant_controller() AssistantSource::kHotkey);
->interaction_controller()
->ToggleInteraction();
} }
} }
......
...@@ -18,9 +18,20 @@ namespace ash { ...@@ -18,9 +18,20 @@ namespace ash {
AssistantController::AssistantController() AssistantController::AssistantController()
: assistant_interaction_controller_( : assistant_interaction_controller_(
std::make_unique<AssistantInteractionController>()), std::make_unique<AssistantInteractionController>()),
assistant_ui_controller_(std::make_unique<AssistantUiController>(this)) {} assistant_ui_controller_(std::make_unique<AssistantUiController>(this)) {
// Note that the sub-controllers have a circular dependency.
// TODO(dmblack): Remove this circular dependency.
assistant_interaction_controller_->SetAssistantUiController(
assistant_ui_controller_.get());
assistant_ui_controller_->SetAssistantInteractionController(
assistant_interaction_controller_.get());
}
AssistantController::~AssistantController() = default; AssistantController::~AssistantController() {
// Explicitly clean up the circular dependency in the sub-controllers.
assistant_interaction_controller_->SetAssistantUiController(nullptr);
assistant_ui_controller_->SetAssistantInteractionController(nullptr);
}
void AssistantController::BindRequest( void AssistantController::BindRequest(
mojom::AssistantControllerRequest request) { mojom::AssistantControllerRequest request) {
...@@ -31,8 +42,9 @@ void AssistantController::SetAssistant( ...@@ -31,8 +42,9 @@ void AssistantController::SetAssistant(
chromeos::assistant::mojom::AssistantPtr assistant) { chromeos::assistant::mojom::AssistantPtr assistant) {
assistant_ = std::move(assistant); assistant_ = std::move(assistant);
// Provide reference to interaction controller. // Provide reference to sub-controllers.
assistant_interaction_controller_->SetAssistant(assistant_.get()); assistant_interaction_controller_->SetAssistant(assistant_.get());
assistant_ui_controller_->SetAssistant(assistant_.get());
} }
void AssistantController::SetAssistantImageDownloader( void AssistantController::SetAssistantImageDownloader(
...@@ -44,8 +56,8 @@ void AssistantController::SetAssistantSetup( ...@@ -44,8 +56,8 @@ void AssistantController::SetAssistantSetup(
mojom::AssistantSetupPtr assistant_setup) { mojom::AssistantSetupPtr assistant_setup) {
assistant_setup_ = std::move(assistant_setup); assistant_setup_ = std::move(assistant_setup);
// Provide reference to interaction controller. // Provide reference to UI controller.
assistant_interaction_controller_->SetAssistantSetup(assistant_setup_.get()); assistant_ui_controller_->SetAssistantSetup(assistant_setup_.get());
} }
void AssistantController::SetWebContentsManager( void AssistantController::SetWebContentsManager(
...@@ -90,6 +102,7 @@ void AssistantController::ManageWebContents( ...@@ -90,6 +102,7 @@ void AssistantController::ManageWebContents(
params->account_id = user_session->user_info->account_id; params->account_id = user_session->user_info->account_id;
// Specify that we will handle top level browser requests. // Specify that we will handle top level browser requests.
// TODO(dmblack): Make AssistantController the OpenUrl delegate.
ash::mojom::ManagedWebContentsOpenUrlDelegatePtr ptr; ash::mojom::ManagedWebContentsOpenUrlDelegatePtr ptr;
web_contents_open_url_delegate_bindings_.AddBinding( web_contents_open_url_delegate_bindings_.AddBinding(
assistant_interaction_controller_.get(), mojo::MakeRequest(&ptr)); assistant_interaction_controller_.get(), mojo::MakeRequest(&ptr));
......
...@@ -7,7 +7,6 @@ ...@@ -7,7 +7,6 @@
#include <memory> #include <memory>
#include "ash/assistant/assistant_ui_controller.h" #include "ash/assistant/assistant_ui_controller.h"
#include "ash/highlighter/highlighter_controller.h"
#include "ash/shell.h" #include "ash/shell.h"
#include "ash/test/ash_test_base.h" #include "ash/test/ash_test_base.h"
#include "base/macros.h" #include "base/macros.h"
...@@ -42,11 +41,11 @@ class AssistantControllerTest : public AshTestBase { ...@@ -42,11 +41,11 @@ class AssistantControllerTest : public AshTestBase {
assistant_binding_->Bind(mojo::MakeRequest(&assistant)); assistant_binding_->Bind(mojo::MakeRequest(&assistant));
controller_->SetAssistant(std::move(assistant)); controller_->SetAssistant(std::move(assistant));
ASSERT_FALSE(IsAssistantUiShown()); ASSERT_FALSE(IsAssistantUiVisible());
} }
bool IsAssistantUiShown() { bool IsAssistantUiVisible() {
return controller_->ui_controller()->IsVisible(); return controller_->ui_controller()->model()->visible();
} }
private: private:
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "ash/assistant/model/assistant_interaction_model.h" #include "ash/assistant/model/assistant_interaction_model.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_observer.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"
#include "ash/public/interfaces/web_contents_manager.mojom.h" #include "ash/public/interfaces/web_contents_manager.mojom.h"
...@@ -21,14 +22,12 @@ ...@@ -21,14 +22,12 @@
namespace ash { namespace ash {
class AssistantInteractionModelObserver; class AssistantInteractionModelObserver;
class AssistantUiController;
namespace mojom {
class AssistantSetup;
} // namespace mojom
class AssistantInteractionController class AssistantInteractionController
: public chromeos::assistant::mojom::AssistantEventSubscriber, : public chromeos::assistant::mojom::AssistantEventSubscriber,
public AssistantInteractionModelObserver, public AssistantInteractionModelObserver,
public AssistantUiModelObserver,
public HighlighterController::Observer, public HighlighterController::Observer,
public DialogPlateDelegate, public DialogPlateDelegate,
public mojom::ManagedWebContentsOpenUrlDelegate { public mojom::ManagedWebContentsOpenUrlDelegate {
...@@ -39,14 +38,15 @@ class AssistantInteractionController ...@@ -39,14 +38,15 @@ class AssistantInteractionController
using AssistantInteractionResolution = using AssistantInteractionResolution =
chromeos::assistant::mojom::AssistantInteractionResolution; chromeos::assistant::mojom::AssistantInteractionResolution;
explicit AssistantInteractionController(); AssistantInteractionController();
~AssistantInteractionController() override; ~AssistantInteractionController() override;
// Provides a pointer to the |assistant| owned by AssistantController. // Provides a pointer to the |assistant| owned by AssistantController.
void SetAssistant(chromeos::assistant::mojom::Assistant* assistant); void SetAssistant(chromeos::assistant::mojom::Assistant* assistant);
// Provides a pointer to the |assistant_setup| owned by AssistantController. // Provides a pointer to the |assistant_ui_controller| owned by
void SetAssistantSetup(mojom::AssistantSetup* assistant_setup); // AssistantController.
void SetAssistantUiController(AssistantUiController* assistant_ui_controller);
// Returns a reference to the underlying model. // Returns a reference to the underlying model.
const AssistantInteractionModel* model() const { const AssistantInteractionModel* model() const {
...@@ -57,19 +57,16 @@ class AssistantInteractionController ...@@ -57,19 +57,16 @@ class AssistantInteractionController
void AddModelObserver(AssistantInteractionModelObserver* observer); void AddModelObserver(AssistantInteractionModelObserver* observer);
void RemoveModelObserver(AssistantInteractionModelObserver* observer); void RemoveModelObserver(AssistantInteractionModelObserver* observer);
// Invoke to modify the Assistant interaction state.
void StartInteraction();
void StopInteraction();
void ToggleInteraction();
// Invoked on suggestion chip pressed event. // Invoked on suggestion chip pressed event.
void OnSuggestionChipPressed(int id); void OnSuggestionChipPressed(int id);
// AssistantInteractionModelObserver: // AssistantInteractionModelObserver:
void OnInputModalityChanged(InputModality input_modality) override; void OnInputModalityChanged(InputModality input_modality) override;
void OnInteractionStateChanged(InteractionState interaction_state) override;
void OnCommittedQueryChanged(const AssistantQuery& committed_query) override; void OnCommittedQueryChanged(const AssistantQuery& committed_query) override;
// AssistantUiModelObserver:
void OnUiVisibilityChanged(bool visible, AssistantSource source) override;
// HighlighterController::Observer: // HighlighterController::Observer:
void OnHighlighterEnabledChanged(HighlighterEnabledState state) override; void OnHighlighterEnabledChanged(HighlighterEnabledState state) override;
...@@ -98,23 +95,22 @@ class AssistantInteractionController ...@@ -98,23 +95,22 @@ class AssistantInteractionController
void OnDialogPlateContentsCommitted(const std::string& text) override; void OnDialogPlateContentsCommitted(const std::string& text) override;
private: private:
void OpenUrl(const GURL& url); void StartTextInteraction(const std::string text);
void StartVoiceInteraction();
mojo::Binding<chromeos::assistant::mojom::AssistantEventSubscriber> void StopActiveInteraction();
assistant_event_subscriber_binding_;
AssistantInteractionModel assistant_interaction_model_; void OpenUrl(const GURL& url);
// Owned by AssistantController. // Owned by AssistantController.
chromeos::assistant::mojom::Assistant* assistant_ = nullptr; chromeos::assistant::mojom::Assistant* assistant_ = nullptr;
// Owned by AssistantController. // Owned by AssisantController.
mojom::AssistantSetup* assistant_setup_ = nullptr; AssistantUiController* assistant_ui_controller_ = nullptr;
// Indicates whether or not there is an active interaction in progress. If mojo::Binding<chromeos::assistant::mojom::AssistantEventSubscriber>
// there is no active interaction, UI related service events should be assistant_event_subscriber_binding_;
// discarded.
bool has_active_interaction_; AssistantInteractionModel assistant_interaction_model_;
DISALLOW_COPY_AND_ASSIGN(AssistantInteractionController); DISALLOW_COPY_AND_ASSIGN(AssistantInteractionController);
}; };
......
...@@ -7,23 +7,70 @@ ...@@ -7,23 +7,70 @@
#include "ash/assistant/assistant_controller.h" #include "ash/assistant/assistant_controller.h"
#include "ash/assistant/assistant_interaction_controller.h" #include "ash/assistant/assistant_interaction_controller.h"
#include "ash/assistant/ui/assistant_container_view.h" #include "ash/assistant/ui/assistant_container_view.h"
#include "ash/public/interfaces/assistant_setup.mojom.h"
#include "ash/shell.h"
#include "ash/strings/grit/ash_strings.h"
#include "ash/system/toast/toast_data.h"
#include "ash/system/toast/toast_manager.h"
#include "ash/voice_interaction/voice_interaction_controller.h"
#include "base/optional.h" #include "base/optional.h"
#include "chromeos/services/assistant/public/mojom/assistant.mojom.h"
#include "ui/base/l10n/l10n_util.h"
namespace ash { namespace ash {
namespace {
// Toast -----------------------------------------------------------------------
constexpr int kToastDurationMs = 2500;
constexpr char kUnboundServiceToastId[] =
"assistant_controller_unbound_service";
void ShowToast(const std::string& id, int message_id) {
ToastData toast(id, l10n_util::GetStringUTF16(message_id), kToastDurationMs,
base::nullopt);
Shell::Get()->toast_manager()->Show(toast);
}
} // namespace
// AssistantUiController -------------------------------------------------------
AssistantUiController::AssistantUiController( AssistantUiController::AssistantUiController(
AssistantController* assistant_controller) AssistantController* assistant_controller)
: assistant_controller_(assistant_controller) { : assistant_controller_(assistant_controller) {
assistant_controller_->interaction_controller()->AddModelObserver(this); Shell::Get()->highlighter_controller()->AddObserver(this);
} }
AssistantUiController::~AssistantUiController() { AssistantUiController::~AssistantUiController() {
assistant_controller_->interaction_controller()->RemoveModelObserver(this); Shell::Get()->highlighter_controller()->RemoveObserver(this);
if (container_view_) if (container_view_)
container_view_->GetWidget()->RemoveObserver(this); container_view_->GetWidget()->RemoveObserver(this);
} }
void AssistantUiController::SetAssistant(
chromeos::assistant::mojom::Assistant* assistant) {
assistant_ = assistant;
}
void AssistantUiController::SetAssistantInteractionController(
AssistantInteractionController* assistant_interaction_controller) {
if (assistant_interaction_controller_)
assistant_interaction_controller_->RemoveModelObserver(this);
assistant_interaction_controller_ = assistant_interaction_controller;
if (assistant_interaction_controller_)
assistant_interaction_controller_->AddModelObserver(this);
}
void AssistantUiController::SetAssistantSetup(
mojom::AssistantSetup* assistant_setup) {
assistant_setup_ = assistant_setup;
}
void AssistantUiController::AddModelObserver( void AssistantUiController::AddModelObserver(
AssistantUiModelObserver* observer) { AssistantUiModelObserver* observer) {
assistant_ui_model_.AddObserver(observer); assistant_ui_model_.AddObserver(observer);
...@@ -46,13 +93,10 @@ void AssistantUiController::OnWidgetVisibilityChanged(views::Widget* widget, ...@@ -46,13 +93,10 @@ void AssistantUiController::OnWidgetVisibilityChanged(views::Widget* widget,
} }
void AssistantUiController::OnWidgetDestroying(views::Widget* widget) { void AssistantUiController::OnWidgetDestroying(views::Widget* widget) {
// We need to be sure that the Assistant interaction is stopped when the // We need to update the model when the widget is destroyed as this may not
// widget is closed. Special cases, such as closing the widget via the |ESC| // have occurred due to a call to HideUi/ToggleUi. This can occur as the
// key might otherwise go unhandled, causing inconsistencies between the // result of pressing the ESC key.
// widget visibility state and the underlying interaction model state. assistant_ui_model_.SetVisible(false, AssistantSource::kUnspecified);
// TODO(dmblack): Clean this up. Sibling controllers shouldn't need to
// communicate to each other directly in this way.
assistant_controller_->interaction_controller()->StopInteraction();
container_view_->GetWidget()->RemoveObserver(this); container_view_->GetWidget()->RemoveObserver(this);
container_view_ = nullptr; container_view_ = nullptr;
...@@ -65,14 +109,13 @@ void AssistantUiController::OnInputModalityChanged( ...@@ -65,14 +109,13 @@ void AssistantUiController::OnInputModalityChanged(
void AssistantUiController::OnInteractionStateChanged( void AssistantUiController::OnInteractionStateChanged(
InteractionState interaction_state) { InteractionState interaction_state) {
switch (interaction_state) { if (interaction_state != InteractionState::kActive)
case InteractionState::kActive: return;
Show();
break; // If there is an active interaction, we need to show Assistant UI if it is
case InteractionState::kInactive: // not already showing. An interaction can only be started when the Assistant
Dismiss(); // UI is hidden if the entry point is hotword.
break; ShowUi(AssistantSource::kHotword);
}
} }
void AssistantUiController::OnMicStateChanged(MicState mic_state) { void AssistantUiController::OnMicStateChanged(MicState mic_state) {
...@@ -97,21 +140,64 @@ void AssistantUiController::OnDialogPlateButtonPressed(DialogPlateButtonId id) { ...@@ -97,21 +140,64 @@ void AssistantUiController::OnDialogPlateButtonPressed(DialogPlateButtonId id) {
UpdateUiMode(AssistantUiMode::kWebUi); UpdateUiMode(AssistantUiMode::kWebUi);
} }
bool AssistantUiController::IsVisible() const { void AssistantUiController::OnHighlighterEnabledChanged(
return container_view_ && container_view_->GetWidget()->IsVisible(); HighlighterEnabledState state) {
switch (state) {
case HighlighterEnabledState::kEnabled:
if (!assistant_ui_model_.visible())
ShowUi(AssistantSource::kStylus);
break;
case HighlighterEnabledState::kDisabledByUser:
if (assistant_ui_model_.visible())
HideUi(AssistantSource::kStylus);
break;
case HighlighterEnabledState::kDisabledBySessionEnd:
// No action necessary.
break;
}
} }
void AssistantUiController::Show() { void AssistantUiController::ShowUi(AssistantSource source) {
if (!Shell::Get()->voice_interaction_controller()->setup_completed()) {
assistant_setup_->StartAssistantOptInFlow();
return;
}
if (!Shell::Get()->voice_interaction_controller()->settings_enabled())
return;
if (!assistant_) {
ShowToast(kUnboundServiceToastId, IDS_ASH_ASSISTANT_ERROR_GENERIC);
return;
}
if (assistant_ui_model_.visible())
return;
if (!container_view_) { if (!container_view_) {
container_view_ = new AssistantContainerView(assistant_controller_); container_view_ = new AssistantContainerView(assistant_controller_);
container_view_->GetWidget()->AddObserver(this); container_view_->GetWidget()->AddObserver(this);
} }
container_view_->GetWidget()->Show(); container_view_->GetWidget()->Show();
assistant_ui_model_.SetVisible(true, source);
} }
void AssistantUiController::Dismiss() { void AssistantUiController::HideUi(AssistantSource source) {
if (!assistant_ui_model_.visible())
return;
if (container_view_) if (container_view_)
container_view_->GetWidget()->Hide(); container_view_->GetWidget()->Hide();
assistant_ui_model_.SetVisible(false, source);
}
void AssistantUiController::ToggleUi(AssistantSource source) {
if (assistant_ui_model_.visible())
HideUi(source);
else
ShowUi(source);
} }
void AssistantUiController::UpdateUiMode( void AssistantUiController::UpdateUiMode(
...@@ -123,29 +209,13 @@ void AssistantUiController::UpdateUiMode( ...@@ -123,29 +209,13 @@ void AssistantUiController::UpdateUiMode(
return; return;
} }
// When Assistant UI is not visible, we should reset to main UI mode.
if (!IsVisible()) {
assistant_ui_model_.SetUiMode(AssistantUiMode::kMainUi);
return;
}
const AssistantInteractionModel* interaction_model =
assistant_controller_->interaction_controller()->model();
// When the mic is open, we should be in main UI mode.
if (interaction_model->mic_state() == MicState::kOpen) {
assistant_ui_model_.SetUiMode(AssistantUiMode::kMainUi);
return;
}
// When stylus input modality is selected, we should be in mini UI mode. // When stylus input modality is selected, we should be in mini UI mode.
if (interaction_model->input_modality() == InputModality::kStylus) { // Otherwise we fall back to main UI mode.
assistant_ui_model_.SetUiMode(AssistantUiMode::kMiniUi); assistant_ui_model_.SetUiMode(
return; assistant_interaction_controller_->model()->input_modality() ==
} InputModality::kStylus
? AssistantUiMode::kMiniUi
// By default, we will fall back to main UI mode. : AssistantUiMode::kMainUi);
assistant_ui_model_.SetUiMode(AssistantUiMode::kMainUi);
} }
} // namespace ash } // namespace ash
...@@ -10,9 +10,18 @@ ...@@ -10,9 +10,18 @@
#include "ash/assistant/model/assistant_ui_model.h" #include "ash/assistant/model/assistant_ui_model.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 "base/macros.h" #include "base/macros.h"
#include "ui/views/widget/widget_observer.h" #include "ui/views/widget/widget_observer.h"
namespace chromeos {
namespace assistant {
namespace mojom {
class Assistant;
} // namespace mojom
} // namespace assistant
} // namespace chromeos
namespace views { namespace views {
class Widget; class Widget;
} // namespace views } // namespace views
...@@ -21,16 +30,33 @@ namespace ash { ...@@ -21,16 +30,33 @@ namespace ash {
class AssistantContainerView; class AssistantContainerView;
class AssistantController; class AssistantController;
class AssistantInteractionController;
namespace mojom {
class AssistantSetup;
} // namespace mojom
class ASH_EXPORT AssistantUiController class ASH_EXPORT AssistantUiController
: public views::WidgetObserver, : public views::WidgetObserver,
public AssistantInteractionModelObserver, public AssistantInteractionModelObserver,
public CaptionBarDelegate, public CaptionBarDelegate,
public DialogPlateDelegate { public DialogPlateDelegate,
public HighlighterController::Observer {
public: public:
explicit AssistantUiController(AssistantController* assistant_controller); explicit AssistantUiController(AssistantController* assistant_controller);
~AssistantUiController() override; ~AssistantUiController() override;
// Provides a pointer to the |assistant| owned by AssistantController.
void SetAssistant(chromeos::assistant::mojom::Assistant* assistant);
// Provides a pointer to the |assistant_interaction_controller| owned by
// AssistantController.
void SetAssistantInteractionController(
AssistantInteractionController* assistant_interaction_controller);
// Provides a pointer to the |assistant_setup| owned by AssistantController.
void SetAssistantSetup(mojom::AssistantSetup* assistant_setup);
// Returns the underlying model. // Returns the underlying model.
const AssistantUiModel* model() const { return &assistant_ui_model_; } const AssistantUiModel* model() const { return &assistant_ui_model_; }
...@@ -54,19 +80,29 @@ class ASH_EXPORT AssistantUiController ...@@ -54,19 +80,29 @@ class ASH_EXPORT AssistantUiController
// DialogPlateDelegate: // DialogPlateDelegate:
void OnDialogPlateButtonPressed(DialogPlateButtonId id) override; void OnDialogPlateButtonPressed(DialogPlateButtonId id) override;
// Returns true if assistant bubble is visible, otherwise false. // HighlighterController::Observer:
bool IsVisible() const; void OnHighlighterEnabledChanged(HighlighterEnabledState state) override;
private: void ShowUi(AssistantSource source);
void Show(); void HideUi(AssistantSource source);
void Dismiss(); void ToggleUi(AssistantSource source);
private:
// Updates UI mode to |ui_mode| if specified. Otherwise UI mode is updated on // Updates UI mode to |ui_mode| if specified. Otherwise UI mode is updated on
// the basis of interaction/widget visibility state. // the basis of interaction/widget visibility state.
void UpdateUiMode(base::Optional<AssistantUiMode> ui_mode = base::nullopt); void UpdateUiMode(base::Optional<AssistantUiMode> ui_mode = base::nullopt);
AssistantController* const assistant_controller_; // Owned by Shell. AssistantController* const assistant_controller_; // Owned by Shell.
// Owned by AssistantController.
chromeos::assistant::mojom::Assistant* assistant_ = nullptr;
// Owned by AssistantController.
AssistantInteractionController* assistant_interaction_controller_ = nullptr;
// Owned by AssistantController.
mojom::AssistantSetup* assistant_setup_ = nullptr;
AssistantUiModel assistant_ui_model_; AssistantUiModel assistant_ui_model_;
AssistantContainerView* container_view_ = AssistantContainerView* container_view_ =
......
...@@ -28,9 +28,22 @@ void AssistantUiModel::SetUiMode(AssistantUiMode ui_mode) { ...@@ -28,9 +28,22 @@ void AssistantUiModel::SetUiMode(AssistantUiMode ui_mode) {
NotifyUiModeChanged(); NotifyUiModeChanged();
} }
void AssistantUiModel::SetVisible(bool visible, AssistantSource source) {
if (visible == visible_)
return;
visible_ = visible;
NotifyUiVisibilityChanged(source);
}
void AssistantUiModel::NotifyUiModeChanged() { void AssistantUiModel::NotifyUiModeChanged() {
for (AssistantUiModelObserver& observer : observers_) for (AssistantUiModelObserver& observer : observers_)
observer.OnUiModeChanged(ui_mode_); observer.OnUiModeChanged(ui_mode_);
} }
void AssistantUiModel::NotifyUiVisibilityChanged(AssistantSource source) {
for (AssistantUiModelObserver& observer : observers_)
observer.OnUiVisibilityChanged(visible_, source);
}
} // namespace ash } // namespace ash
...@@ -12,6 +12,15 @@ namespace ash { ...@@ -12,6 +12,15 @@ namespace ash {
class AssistantUiModelObserver; class AssistantUiModelObserver;
// Enumeration of Assistant entry/exit points.
enum class AssistantSource {
kUnspecified,
kHotkey,
kHotword,
kLongPressLauncher,
kStylus,
};
// Enumeration of Assistant UI modes. // Enumeration of Assistant UI modes.
enum class AssistantUiMode { enum class AssistantUiMode {
kMainUi, kMainUi,
...@@ -35,11 +44,19 @@ class AssistantUiModel { ...@@ -35,11 +44,19 @@ class AssistantUiModel {
// Returns the UI mode. // Returns the UI mode.
AssistantUiMode ui_mode() const { return ui_mode_; } AssistantUiMode ui_mode() const { return ui_mode_; }
// Sets the UI visibility.
void SetVisible(bool visible, AssistantSource source);
bool visible() const { return visible_; }
private: private:
void NotifyUiModeChanged(); void NotifyUiModeChanged();
void NotifyUiVisibilityChanged(AssistantSource source);
AssistantUiMode ui_mode_ = AssistantUiMode::kMainUi; AssistantUiMode ui_mode_ = AssistantUiMode::kMainUi;
bool visible_ = false;
base::ObserverList<AssistantUiModelObserver> observers_; base::ObserverList<AssistantUiModelObserver> observers_;
DISALLOW_COPY_AND_ASSIGN(AssistantUiModel); DISALLOW_COPY_AND_ASSIGN(AssistantUiModel);
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
namespace ash { namespace ash {
enum class AssistantSource;
enum class AssistantUiMode; enum class AssistantUiMode;
// An observer which receives notification of changes to the Assistant UI model. // An observer which receives notification of changes to the Assistant UI model.
...@@ -17,6 +18,10 @@ class AssistantUiModelObserver { ...@@ -17,6 +18,10 @@ class AssistantUiModelObserver {
// Invoked when the UI mode is changed. // Invoked when the UI mode is changed.
virtual void OnUiModeChanged(AssistantUiMode ui_mode) {} virtual void OnUiModeChanged(AssistantUiMode ui_mode) {}
// Invoked when the UI visibility is changed. The |source| of the visibility
// change event is provided for interested observers.
virtual void OnUiVisibilityChanged(bool visible, AssistantSource source) {}
protected: protected:
AssistantUiModelObserver() = default; AssistantUiModelObserver() = default;
virtual ~AssistantUiModelObserver() = default; virtual ~AssistantUiModelObserver() = default;
......
...@@ -7,7 +7,6 @@ ...@@ -7,7 +7,6 @@
#include <memory> #include <memory>
#include "ash/assistant/assistant_controller.h" #include "ash/assistant/assistant_controller.h"
#include "ash/assistant/assistant_interaction_controller.h"
#include "ash/assistant/assistant_ui_controller.h" #include "ash/assistant/assistant_ui_controller.h"
#include "ash/assistant/model/assistant_interaction_model.h" #include "ash/assistant/model/assistant_interaction_model.h"
#include "ash/assistant/ui/assistant_ui_constants.h" #include "ash/assistant/ui/assistant_ui_constants.h"
...@@ -34,12 +33,13 @@ AssistantMainView::AssistantMainView(AssistantController* assistant_controller) ...@@ -34,12 +33,13 @@ AssistantMainView::AssistantMainView(AssistantController* assistant_controller)
caption_bar_->set_delegate(assistant_controller_->ui_controller()); caption_bar_->set_delegate(assistant_controller_->ui_controller());
dialog_plate_->set_delegate(assistant_controller_); dialog_plate_->set_delegate(assistant_controller_);
// Observe changes to interaction model. // The AssistantController indirectly owns the view hierarchy to which
assistant_controller_->interaction_controller()->AddModelObserver(this); // AssistantMainView belongs so is guaranteed to outlive it.
assistant_controller_->ui_controller()->AddModelObserver(this);
} }
AssistantMainView::~AssistantMainView() { AssistantMainView::~AssistantMainView() {
assistant_controller_->interaction_controller()->RemoveModelObserver(this); assistant_controller_->ui_controller()->RemoveModelObserver(this);
} }
gfx::Size AssistantMainView::CalculatePreferredSize() const { gfx::Size AssistantMainView::CalculatePreferredSize() const {
...@@ -92,9 +92,9 @@ void AssistantMainView::InitLayout() { ...@@ -92,9 +92,9 @@ void AssistantMainView::InitLayout() {
AddChildView(dialog_plate_); AddChildView(dialog_plate_);
} }
void AssistantMainView::OnInteractionStateChanged( void AssistantMainView::OnUiVisibilityChanged(bool visible,
InteractionState interaction_state) { AssistantSource source) {
if (interaction_state != InteractionState::kInactive) if (visible)
return; return;
// When the Assistant UI is being hidden we need to reset our minimum height // When the Assistant UI is being hidden we need to reset our minimum height
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
#ifndef ASH_ASSISTANT_UI_ASSISTANT_MAIN_VIEW_H_ #ifndef ASH_ASSISTANT_UI_ASSISTANT_MAIN_VIEW_H_
#define ASH_ASSISTANT_UI_ASSISTANT_MAIN_VIEW_H_ #define ASH_ASSISTANT_UI_ASSISTANT_MAIN_VIEW_H_
#include "ash/assistant/model/assistant_interaction_model_observer.h" #include "ash/assistant/model/assistant_ui_model_observer.h"
#include "base/macros.h" #include "base/macros.h"
#include "ui/views/view.h" #include "ui/views/view.h"
...@@ -16,8 +16,7 @@ class AssistantMainStage; ...@@ -16,8 +16,7 @@ class AssistantMainStage;
class CaptionBar; class CaptionBar;
class DialogPlate; class DialogPlate;
class AssistantMainView : public views::View, class AssistantMainView : public views::View, public AssistantUiModelObserver {
public AssistantInteractionModelObserver {
public: public:
explicit AssistantMainView(AssistantController* assistant_controller); explicit AssistantMainView(AssistantController* assistant_controller);
~AssistantMainView() override; ~AssistantMainView() override;
...@@ -29,8 +28,8 @@ class AssistantMainView : public views::View, ...@@ -29,8 +28,8 @@ class AssistantMainView : public views::View,
void OnBoundsChanged(const gfx::Rect& prev_bounds) override; void OnBoundsChanged(const gfx::Rect& prev_bounds) override;
void RequestFocus() override; void RequestFocus() override;
// AssistantInteractionModelObserver: // AssistantUiModelObserver:
void OnInteractionStateChanged(InteractionState interaction_state) override; void OnUiVisibilityChanged(bool visible, AssistantSource source) override;
private: private:
void InitLayout(); void InitLayout();
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include "ash/assistant/assistant_controller.h" #include "ash/assistant/assistant_controller.h"
#include "ash/assistant/assistant_interaction_controller.h" #include "ash/assistant/assistant_interaction_controller.h"
#include "ash/assistant/assistant_ui_controller.h"
#include "ash/assistant/ui/assistant_ui_constants.h" #include "ash/assistant/ui/assistant_ui_constants.h"
#include "ash/public/cpp/vector_icons/vector_icons.h" #include "ash/public/cpp/vector_icons/vector_icons.h"
#include "ash/resources/vector_icons/vector_icons.h" #include "ash/resources/vector_icons/vector_icons.h"
...@@ -57,9 +58,11 @@ DialogPlate::DialogPlate(AssistantController* assistant_controller) ...@@ -57,9 +58,11 @@ DialogPlate::DialogPlate(AssistantController* assistant_controller)
// The Assistant controller indirectly owns the view hierarchy to which // The Assistant controller indirectly owns the view hierarchy to which
// DialogPlate belongs so is guaranteed to outlive it. // DialogPlate belongs so is guaranteed to outlive it.
assistant_controller_->interaction_controller()->AddModelObserver(this); assistant_controller_->interaction_controller()->AddModelObserver(this);
assistant_controller_->ui_controller()->AddModelObserver(this);
} }
DialogPlate::~DialogPlate() { DialogPlate::~DialogPlate() {
assistant_controller_->ui_controller()->RemoveModelObserver(this);
assistant_controller_->interaction_controller()->RemoveModelObserver(this); assistant_controller_->interaction_controller()->RemoveModelObserver(this);
} }
...@@ -220,11 +223,10 @@ void DialogPlate::OnInputModalityChanged(InputModality input_modality) { ...@@ -220,11 +223,10 @@ void DialogPlate::OnInputModalityChanged(InputModality input_modality) {
} }
} }
void DialogPlate::OnInteractionStateChanged( void DialogPlate::OnUiVisibilityChanged(bool visible, AssistantSource source) {
InteractionState interaction_state) { // When the Assistant UI is hidden we need to clear the dialog plate so that
// When the Assistant interaction becomes inactive we need to clear the // text does not persist across Assistant entries.
// dialog plate so that text does not persist across Assistant entries. if (!visible)
if (interaction_state == InteractionState::kInactive)
textfield_->SetText(base::string16()); textfield_->SetText(base::string16());
} }
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include <string> #include <string>
#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_observer.h"
#include "ash/assistant/ui/dialog_plate/action_view.h" #include "ash/assistant/ui/dialog_plate/action_view.h"
#include "base/macros.h" #include "base/macros.h"
#include "ui/views/controls/button/button.h" #include "ui/views/controls/button/button.h"
...@@ -55,6 +56,7 @@ class DialogPlate : public views::View, ...@@ -55,6 +56,7 @@ class DialogPlate : public views::View,
public views::TextfieldController, public views::TextfieldController,
public ActionViewListener, public ActionViewListener,
public AssistantInteractionModelObserver, public AssistantInteractionModelObserver,
public AssistantUiModelObserver,
public views::ButtonListener { public views::ButtonListener {
public: public:
explicit DialogPlate(AssistantController* assistant_controller); explicit DialogPlate(AssistantController* assistant_controller);
...@@ -79,7 +81,9 @@ class DialogPlate : public views::View, ...@@ -79,7 +81,9 @@ class DialogPlate : public views::View,
// AssistantInteractionModelObserver: // AssistantInteractionModelObserver:
void OnInputModalityChanged(InputModality input_modality) override; void OnInputModalityChanged(InputModality input_modality) override;
void OnInteractionStateChanged(InteractionState interaction_state) override;
// AssistantUiModelObserver:
void OnUiVisibilityChanged(bool visible, AssistantSource source) override;
void set_delegate(DialogPlateDelegate* delegate) { delegate_ = delegate; } void set_delegate(DialogPlateDelegate* delegate) { delegate_ = delegate; }
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include "ash/assistant/assistant_controller.h" #include "ash/assistant/assistant_controller.h"
#include "ash/assistant/assistant_interaction_controller.h" #include "ash/assistant/assistant_interaction_controller.h"
#include "ash/assistant/assistant_ui_controller.h"
#include "ash/assistant/model/assistant_interaction_model.h" #include "ash/assistant/model/assistant_interaction_model.h"
#include "ash/assistant/model/assistant_query.h" #include "ash/assistant/model/assistant_query.h"
#include "ash/assistant/ui/assistant_ui_constants.h" #include "ash/assistant/ui/assistant_ui_constants.h"
...@@ -37,9 +38,11 @@ AssistantHeaderView::AssistantHeaderView( ...@@ -37,9 +38,11 @@ AssistantHeaderView::AssistantHeaderView(
// The Assistant controller indirectly owns the view hierarchy to which // The Assistant controller indirectly owns the view hierarchy to which
// AssistantHeaderView belongs so is guaranteed to outlive it. // AssistantHeaderView belongs so is guaranteed to outlive it.
assistant_controller_->interaction_controller()->AddModelObserver(this); assistant_controller_->interaction_controller()->AddModelObserver(this);
assistant_controller_->ui_controller()->AddModelObserver(this);
} }
AssistantHeaderView::~AssistantHeaderView() { AssistantHeaderView::~AssistantHeaderView() {
assistant_controller_->ui_controller()->RemoveModelObserver(this);
assistant_controller_->interaction_controller()->RemoveModelObserver(this); assistant_controller_->interaction_controller()->RemoveModelObserver(this);
} }
...@@ -90,17 +93,16 @@ void AssistantHeaderView::InitLayout() { ...@@ -90,17 +93,16 @@ void AssistantHeaderView::InitLayout() {
AddChildView(label_); AddChildView(label_);
} }
void AssistantHeaderView::OnInteractionStateChanged(
InteractionState interaction_state) {
if (interaction_state != InteractionState::kInactive)
return;
label_->SetVisible(true);
}
void AssistantHeaderView::OnCommittedQueryChanged( void AssistantHeaderView::OnCommittedQueryChanged(
const AssistantQuery& committed_query) { const AssistantQuery& committed_query) {
label_->SetVisible(false); label_->SetVisible(false);
} }
void AssistantHeaderView::OnUiVisibilityChanged(bool visible,
AssistantSource source) {
// When Assistant UI is being hidden, we need to restore default view state.
if (!visible)
label_->SetVisible(true);
}
} // namespace ash } // namespace ash
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#define ASH_ASSISTANT_UI_MAIN_STAGE_ASSISTANT_HEADER_VIEW_H_ #define ASH_ASSISTANT_UI_MAIN_STAGE_ASSISTANT_HEADER_VIEW_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_observer.h"
#include "base/macros.h" #include "base/macros.h"
#include "ui/views/view.h" #include "ui/views/view.h"
...@@ -21,7 +22,8 @@ class AssistantController; ...@@ -21,7 +22,8 @@ class AssistantController;
// AssistantHeaderView is the child of UiElementContainerView which provides // AssistantHeaderView is the child of UiElementContainerView which provides
// the Assistant icon. On first launch, it also displays a greeting to the user. // the Assistant icon. On first launch, it also displays a greeting to the user.
class AssistantHeaderView : public views::View, class AssistantHeaderView : public views::View,
public AssistantInteractionModelObserver { public AssistantInteractionModelObserver,
public AssistantUiModelObserver {
public: public:
explicit AssistantHeaderView(AssistantController* assistant_controller); explicit AssistantHeaderView(AssistantController* assistant_controller);
~AssistantHeaderView() override; ~AssistantHeaderView() override;
...@@ -32,9 +34,11 @@ class AssistantHeaderView : public views::View, ...@@ -32,9 +34,11 @@ class AssistantHeaderView : public views::View,
void ChildVisibilityChanged(views::View* child) override; void ChildVisibilityChanged(views::View* child) override;
// AssistantInteractionModelObserver: // AssistantInteractionModelObserver:
void OnInteractionStateChanged(InteractionState interaction_state) override;
void OnCommittedQueryChanged(const AssistantQuery& committed_query) override; void OnCommittedQueryChanged(const AssistantQuery& committed_query) override;
// AssistantUiModelObserver:
void OnUiVisibilityChanged(bool visible, AssistantSource source) override;
private: private:
void InitLayout(); void InitLayout();
......
...@@ -10,7 +10,8 @@ ...@@ -10,7 +10,8 @@
#include "ash/app_list/app_list_controller_impl.h" #include "ash/app_list/app_list_controller_impl.h"
#include "ash/assistant/assistant_controller.h" #include "ash/assistant/assistant_controller.h"
#include "ash/assistant/assistant_interaction_controller.h" #include "ash/assistant/assistant_ui_controller.h"
#include "ash/assistant/model/assistant_ui_model.h"
#include "ash/public/cpp/shelf_types.h" #include "ash/public/cpp/shelf_types.h"
#include "ash/session/session_controller.h" #include "ash/session/session_controller.h"
#include "ash/shelf/assistant_overlay.h" #include "ash/shelf/assistant_overlay.h"
...@@ -142,10 +143,8 @@ void AppListButton::OnGestureEvent(ui::GestureEvent* event) { ...@@ -142,10 +143,8 @@ void AppListButton::OnGestureEvent(ui::GestureEvent* event) {
assistant_overlay_->BurstAnimation(); assistant_overlay_->BurstAnimation();
event->SetHandled(); event->SetHandled();
if (chromeos::switches::IsAssistantEnabled()) { if (chromeos::switches::IsAssistantEnabled()) {
Shell::Get() Shell::Get()->assistant_controller()->ui_controller()->ShowUi(
->assistant_controller() AssistantSource::kLongPressLauncher);
->interaction_controller()
->StartInteraction();
} else { } else {
Shell::Get()->app_list_controller()->StartVoiceInteractionSession(); Shell::Get()->app_list_controller()->StartVoiceInteractionSession();
} }
......
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