blob: 52908a2f4644482a436a2efa474af5401a66c600 [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 "ash/assistant/assistant_ui_controller.h"
#include "ash/assistant/assistant_controller.h"
#include "ash/assistant/assistant_interaction_controller.h"
#include "ash/assistant/ui/assistant_container_view.h"
#include "base/optional.h"
namespace ash {
AssistantUiController::AssistantUiController(
AssistantController* assistant_controller)
: assistant_controller_(assistant_controller) {
assistant_controller_->interaction_controller()->AddModelObserver(this);
}
AssistantUiController::~AssistantUiController() {
assistant_controller_->interaction_controller()->RemoveModelObserver(this);
if (container_view_)
container_view_->GetWidget()->RemoveObserver(this);
}
void AssistantUiController::AddModelObserver(
AssistantUiModelObserver* observer) {
assistant_ui_model_.AddObserver(observer);
}
void AssistantUiController::RemoveModelObserver(
AssistantUiModelObserver* observer) {
assistant_ui_model_.RemoveObserver(observer);
}
void AssistantUiController::OnWidgetActivationChanged(views::Widget* widget,
bool active) {
if (active)
container_view_->RequestFocus();
}
void AssistantUiController::OnWidgetVisibilityChanged(views::Widget* widget,
bool visible) {
UpdateUiMode();
}
void AssistantUiController::OnWidgetDestroying(views::Widget* widget) {
// We need to be sure that the Assistant interaction is stopped when the
// widget is closed. Special cases, such as closing the widget via the |ESC|
// key might otherwise go unhandled, causing inconsistencies between the
// widget visibility state and the underlying interaction model state.
// 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_ = nullptr;
}
void AssistantUiController::OnInputModalityChanged(
InputModality input_modality) {
UpdateUiMode();
}
void AssistantUiController::OnInteractionStateChanged(
InteractionState interaction_state) {
switch (interaction_state) {
case InteractionState::kActive:
Show();
break;
case InteractionState::kInactive:
Dismiss();
break;
}
}
void AssistantUiController::OnMicStateChanged(MicState mic_state) {
UpdateUiMode();
}
bool AssistantUiController::OnCaptionButtonPressed(CaptionButtonId id) {
switch (id) {
case CaptionButtonId::kMinimize:
UpdateUiMode(AssistantUiMode::kMiniUi);
return true;
case CaptionButtonId::kClose:
return false;
}
return false;
}
void AssistantUiController::OnDialogPlateButtonPressed(DialogPlateButtonId id) {
if (id != DialogPlateButtonId::kSettings)
return;
UpdateUiMode(AssistantUiMode::kWebUi);
}
bool AssistantUiController::IsVisible() const {
return container_view_ && container_view_->GetWidget()->IsVisible();
}
void AssistantUiController::Show() {
if (!container_view_) {
container_view_ = new AssistantContainerView(assistant_controller_);
container_view_->GetWidget()->AddObserver(this);
}
container_view_->GetWidget()->Show();
}
void AssistantUiController::Dismiss() {
if (container_view_)
container_view_->GetWidget()->Hide();
}
void AssistantUiController::UpdateUiMode(
base::Optional<AssistantUiMode> ui_mode) {
// If a UI mode is provided, we will use it in lieu of updating UI mode on the
// basis of interaction/widget visibility state.
if (ui_mode.has_value()) {
assistant_ui_model_.SetUiMode(ui_mode.value());
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.
if (interaction_model->input_modality() == InputModality::kStylus) {
assistant_ui_model_.SetUiMode(AssistantUiMode::kMiniUi);
return;
}
// By default, we will fall back to main UI mode.
assistant_ui_model_.SetUiMode(AssistantUiMode::kMainUi);
}
} // namespace ash