Commit 02974f88 authored by David Black's avatar David Black Committed by Commit Bot

Finish conversation starters.

This involved:
- Limiting conversation starter count to 3.
- Shuffling and selecting conversation starters to reach 3.
- Refreshing conversation starter cache for new UI sessions.
- Center aligning conversation starters (but keeping suggestion chips
  for interaction responses start aligned).

Bug: b:111694337
Change-Id: I1b5b94fabcd0a37ce3a3400a670db4224fc6a667
Reviewed-on: https://chromium-review.googlesource.com/1182863
Commit-Queue: David Black <dmblack@google.com>
Reviewed-by: default avatarXiaohui Chen <xiaohuic@chromium.org>
Cr-Commit-Position: refs/heads/master@{#584916}
parent 07d8d2d9
......@@ -6,26 +6,42 @@
#include <vector>
#include "ash/assistant/assistant_controller.h"
#include "ash/assistant/assistant_ui_controller.h"
#include "ash/assistant/util/deep_link_util.h"
#include "ash/shell.h"
#include "ash/strings/grit/ash_strings.h"
#include "ash/voice_interaction/voice_interaction_controller.h"
#include "base/rand_util.h"
#include "chromeos/services/assistant/public/mojom/assistant.mojom.h"
#include "ui/base/l10n/l10n_util.h"
namespace ash {
AssistantCacheController::AssistantCacheController()
: voice_interaction_binding_(this) {
namespace {
// Conversation starters.
constexpr int kNumOfConversationStarters = 3;
} // namespace
AssistantCacheController::AssistantCacheController(
AssistantController* assistant_controller)
: assistant_controller_(assistant_controller),
voice_interaction_binding_(this) {
UpdateConversationStarters();
assistant_controller_->AddObserver(this);
// Bind to observe changes to screen context preference.
mojom::VoiceInteractionObserverPtr ptr;
voice_interaction_binding_.Bind(mojo::MakeRequest(&ptr));
Shell::Get()->voice_interaction_controller()->AddObserver(std::move(ptr));
}
AssistantCacheController::~AssistantCacheController() = default;
AssistantCacheController::~AssistantCacheController() {
assistant_controller_->RemoveObserver(this);
}
void AssistantCacheController::AddModelObserver(
AssistantCacheModelObserver* observer) {
......@@ -37,6 +53,22 @@ void AssistantCacheController::RemoveModelObserver(
model_.RemoveObserver(observer);
}
void AssistantCacheController::OnAssistantControllerConstructed() {
assistant_controller_->ui_controller()->AddModelObserver(this);
}
void AssistantCacheController::OnAssistantControllerDestroying() {
assistant_controller_->ui_controller()->RemoveModelObserver(this);
}
void AssistantCacheController::OnUiVisibilityChanged(bool visible,
AssistantSource source) {
// When hiding the UI we update our cache of conversation starters so that
// they're fresh for the next session.
if (!visible)
UpdateConversationStarters();
}
void AssistantCacheController::OnVoiceInteractionContextEnabled(bool enabled) {
UpdateConversationStarters();
}
......@@ -56,22 +88,34 @@ void AssistantCacheController::UpdateConversationStarters() {
conversation_starters.push_back(std::move(starter));
};
// Always show the "What can you do?" conversation starter.
AddConversationStarter(IDS_ASH_ASSISTANT_CHIP_WHAT_CAN_YOU_DO);
// Always show the "What's on my screen?" conversation starter (if enabled).
if (Shell::Get()->voice_interaction_controller()->context_enabled()) {
AddConversationStarter(IDS_ASH_ASSISTANT_CHIP_WHATS_ON_MY_SCREEN,
assistant::util::CreateWhatsOnMyScreenDeepLink());
}
AddConversationStarter(IDS_ASH_ASSISTANT_CHIP_WHATS_ON_MY_CALENDAR);
// The rest of the conversation starters will be shuffled...
int shuffled_message_ids[] = {
IDS_ASH_ASSISTANT_CHIP_IM_BORED,
IDS_ASH_ASSISTANT_CHIP_OPEN_FILES,
IDS_ASH_ASSISTANT_CHIP_PLAY_MUSIC,
IDS_ASH_ASSISTANT_CHIP_SEND_AN_EMAIL,
IDS_ASH_ASSISTANT_CHIP_SET_A_REMINDER,
IDS_ASH_ASSISTANT_CHIP_WHATS_ON_MY_CALENDAR,
IDS_ASH_ASSISTANT_CHIP_WHATS_THE_WEATHER,
};
base::RandomShuffle(std::begin(shuffled_message_ids),
std::end(shuffled_message_ids));
// TODO(dmblack): Shuffle these chips and limit our total chip count to four.
AddConversationStarter(IDS_ASH_ASSISTANT_CHIP_PLAY_MUSIC);
AddConversationStarter(IDS_ASH_ASSISTANT_CHIP_SEND_AN_EMAIL);
AddConversationStarter(IDS_ASH_ASSISTANT_CHIP_WHATS_THE_WEATHER);
AddConversationStarter(IDS_ASH_ASSISTANT_CHIP_IM_BORED);
AddConversationStarter(IDS_ASH_ASSISTANT_CHIP_OPEN_FILES);
AddConversationStarter(IDS_ASH_ASSISTANT_CHIP_SET_A_REMINDER);
// ...and will be added until we reach |kNumOfConversationStarters|.
for (int i = 0; conversation_starters.size() < kNumOfConversationStarters;
++i) {
AddConversationStarter(shuffled_message_ids[i]);
}
model_.SetConversationStarters(std::move(conversation_starters));
}
......
......@@ -5,7 +5,9 @@
#ifndef ASH_ASSISTANT_ASSISTANT_CACHE_CONTROLLER_H_
#define ASH_ASSISTANT_ASSISTANT_CACHE_CONTROLLER_H_
#include "ash/assistant/assistant_controller_observer.h"
#include "ash/assistant/model/assistant_cache_model.h"
#include "ash/assistant/model/assistant_ui_model_observer.h"
#include "ash/public/interfaces/voice_interaction_controller.mojom.h"
#include "base/macros.h"
#include "mojo/public/cpp/bindings/binding.h"
......@@ -13,10 +15,13 @@
namespace ash {
class AssistantCacheModelObserver;
class AssistantController;
class AssistantCacheController : public mojom::VoiceInteractionObserver {
class AssistantCacheController : public AssistantControllerObserver,
public AssistantUiModelObserver,
public mojom::VoiceInteractionObserver {
public:
AssistantCacheController();
explicit AssistantCacheController(AssistantController* assistant_controller);
~AssistantCacheController() override;
// Returns a reference to the underlying model.
......@@ -26,6 +31,13 @@ class AssistantCacheController : public mojom::VoiceInteractionObserver {
void AddModelObserver(AssistantCacheModelObserver* observer);
void RemoveModelObserver(AssistantCacheModelObserver* observer);
// AssistantControllerObserver:
void OnAssistantControllerConstructed() override;
void OnAssistantControllerDestroying() override;
// AssistantUiModelObserver:
void OnUiVisibilityChanged(bool visible, AssistantSource source) override;
private:
// mojom::VoiceInteractionObserver:
void OnVoiceInteractionStatusChanged(
......@@ -39,6 +51,8 @@ class AssistantCacheController : public mojom::VoiceInteractionObserver {
void UpdateConversationStarters();
AssistantController* const assistant_controller_; // Owned by Shell.
mojo::Binding<mojom::VoiceInteractionObserver> voice_interaction_binding_;
AssistantCacheModel model_;
......
......@@ -25,7 +25,8 @@ namespace ash {
AssistantController::AssistantController()
: assistant_volume_control_binding_(this),
assistant_cache_controller_(std::make_unique<AssistantCacheController>()),
assistant_cache_controller_(
std::make_unique<AssistantCacheController>(this)),
assistant_interaction_controller_(
std::make_unique<AssistantInteractionController>(this)),
assistant_notification_controller_(
......
......@@ -55,18 +55,25 @@ int SuggestionContainerView::GetHeightForWidth(int width) const {
void SuggestionContainerView::OnContentsPreferredSizeChanged(
views::View* content_view) {
const int preferred_width = content_view->GetPreferredSize().width();
content_view->SetSize(gfx::Size(preferred_width, kPreferredHeightDip));
// Our contents should never be smaller than our container width because when
// showing conversation starters we will be center aligned.
const int width =
std::max(content_view->GetPreferredSize().width(), this->width());
content_view->SetSize(gfx::Size(width, kPreferredHeightDip));
}
void SuggestionContainerView::InitLayout() {
views::BoxLayout* layout_manager =
layout_manager_ =
content_view()->SetLayoutManager(std::make_unique<views::BoxLayout>(
views::BoxLayout::Orientation::kHorizontal,
gfx::Insets(0, kPaddingDip), kSpacingDip));
layout_manager->set_cross_axis_alignment(
layout_manager_->set_cross_axis_alignment(
views::BoxLayout::CrossAxisAlignment::CROSS_AXIS_ALIGNMENT_END);
// We center align when showing conversation starters.
layout_manager_->set_main_axis_alignment(
views::BoxLayout::MainAxisAlignment::MAIN_AXIS_ALIGNMENT_CENTER);
}
void SuggestionContainerView::OnConversationStartersChanged(
......@@ -81,6 +88,11 @@ void SuggestionContainerView::OnResponseChanged(
has_received_response_ = true;
OnSuggestionsCleared();
// When no longer showing conversation starters, we start align our content.
layout_manager_->set_main_axis_alignment(
views::BoxLayout::MainAxisAlignment::MAIN_AXIS_ALIGNMENT_START);
OnSuggestionsChanged(response.GetSuggestions());
}
......@@ -183,6 +195,11 @@ void SuggestionContainerView::OnUiVisibilityChanged(bool visible,
} else {
// Reset view state.
has_received_response_ = false;
// When we become visible again we will be showing conversation starters so
// we need to center align our content.
layout_manager_->set_main_axis_alignment(
views::BoxLayout::MainAxisAlignment::MAIN_AXIS_ALIGNMENT_CENTER);
}
}
......
......@@ -16,6 +16,10 @@
#include "chromeos/services/assistant/public/mojom/assistant.mojom.h"
#include "ui/views/controls/scroll_view.h"
namespace views {
class BoxLayout;
} // namespace views
namespace ash {
class AssistantController;
......@@ -68,6 +72,8 @@ class SuggestionContainerView : public AssistantScrollView,
AssistantController* const assistant_controller_; // Owned by Shell.
views::BoxLayout* layout_manager_; // Owned by view hierarchy.
// Cache of suggestion chip views owned by the view hierarchy. The key for the
// map is the unique identifier by which the Assistant interaction model
// identifies the view's underlying suggestion.
......
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