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 @@ ...@@ -6,26 +6,42 @@
#include <vector> #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/assistant/util/deep_link_util.h"
#include "ash/shell.h" #include "ash/shell.h"
#include "ash/strings/grit/ash_strings.h" #include "ash/strings/grit/ash_strings.h"
#include "ash/voice_interaction/voice_interaction_controller.h" #include "ash/voice_interaction/voice_interaction_controller.h"
#include "base/rand_util.h"
#include "chromeos/services/assistant/public/mojom/assistant.mojom.h" #include "chromeos/services/assistant/public/mojom/assistant.mojom.h"
#include "ui/base/l10n/l10n_util.h" #include "ui/base/l10n/l10n_util.h"
namespace ash { namespace ash {
AssistantCacheController::AssistantCacheController() namespace {
: voice_interaction_binding_(this) {
// Conversation starters.
constexpr int kNumOfConversationStarters = 3;
} // namespace
AssistantCacheController::AssistantCacheController(
AssistantController* assistant_controller)
: assistant_controller_(assistant_controller),
voice_interaction_binding_(this) {
UpdateConversationStarters(); UpdateConversationStarters();
assistant_controller_->AddObserver(this);
// Bind to observe changes to screen context preference. // Bind to observe changes to screen context preference.
mojom::VoiceInteractionObserverPtr ptr; mojom::VoiceInteractionObserverPtr ptr;
voice_interaction_binding_.Bind(mojo::MakeRequest(&ptr)); voice_interaction_binding_.Bind(mojo::MakeRequest(&ptr));
Shell::Get()->voice_interaction_controller()->AddObserver(std::move(ptr)); Shell::Get()->voice_interaction_controller()->AddObserver(std::move(ptr));
} }
AssistantCacheController::~AssistantCacheController() = default; AssistantCacheController::~AssistantCacheController() {
assistant_controller_->RemoveObserver(this);
}
void AssistantCacheController::AddModelObserver( void AssistantCacheController::AddModelObserver(
AssistantCacheModelObserver* observer) { AssistantCacheModelObserver* observer) {
...@@ -37,6 +53,22 @@ void AssistantCacheController::RemoveModelObserver( ...@@ -37,6 +53,22 @@ void AssistantCacheController::RemoveModelObserver(
model_.RemoveObserver(observer); 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) { void AssistantCacheController::OnVoiceInteractionContextEnabled(bool enabled) {
UpdateConversationStarters(); UpdateConversationStarters();
} }
...@@ -56,22 +88,34 @@ void AssistantCacheController::UpdateConversationStarters() { ...@@ -56,22 +88,34 @@ void AssistantCacheController::UpdateConversationStarters() {
conversation_starters.push_back(std::move(starter)); 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); 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()) { if (Shell::Get()->voice_interaction_controller()->context_enabled()) {
AddConversationStarter(IDS_ASH_ASSISTANT_CHIP_WHATS_ON_MY_SCREEN, AddConversationStarter(IDS_ASH_ASSISTANT_CHIP_WHATS_ON_MY_SCREEN,
assistant::util::CreateWhatsOnMyScreenDeepLink()); 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. // ...and will be added until we reach |kNumOfConversationStarters|.
AddConversationStarter(IDS_ASH_ASSISTANT_CHIP_PLAY_MUSIC); for (int i = 0; conversation_starters.size() < kNumOfConversationStarters;
AddConversationStarter(IDS_ASH_ASSISTANT_CHIP_SEND_AN_EMAIL); ++i) {
AddConversationStarter(IDS_ASH_ASSISTANT_CHIP_WHATS_THE_WEATHER); AddConversationStarter(shuffled_message_ids[i]);
AddConversationStarter(IDS_ASH_ASSISTANT_CHIP_IM_BORED); }
AddConversationStarter(IDS_ASH_ASSISTANT_CHIP_OPEN_FILES);
AddConversationStarter(IDS_ASH_ASSISTANT_CHIP_SET_A_REMINDER);
model_.SetConversationStarters(std::move(conversation_starters)); model_.SetConversationStarters(std::move(conversation_starters));
} }
......
...@@ -5,7 +5,9 @@ ...@@ -5,7 +5,9 @@
#ifndef ASH_ASSISTANT_ASSISTANT_CACHE_CONTROLLER_H_ #ifndef ASH_ASSISTANT_ASSISTANT_CACHE_CONTROLLER_H_
#define 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_cache_model.h"
#include "ash/assistant/model/assistant_ui_model_observer.h"
#include "ash/public/interfaces/voice_interaction_controller.mojom.h" #include "ash/public/interfaces/voice_interaction_controller.mojom.h"
#include "base/macros.h" #include "base/macros.h"
#include "mojo/public/cpp/bindings/binding.h" #include "mojo/public/cpp/bindings/binding.h"
...@@ -13,10 +15,13 @@ ...@@ -13,10 +15,13 @@
namespace ash { namespace ash {
class AssistantCacheModelObserver; class AssistantCacheModelObserver;
class AssistantController;
class AssistantCacheController : public mojom::VoiceInteractionObserver { class AssistantCacheController : public AssistantControllerObserver,
public AssistantUiModelObserver,
public mojom::VoiceInteractionObserver {
public: public:
AssistantCacheController(); explicit AssistantCacheController(AssistantController* assistant_controller);
~AssistantCacheController() override; ~AssistantCacheController() override;
// Returns a reference to the underlying model. // Returns a reference to the underlying model.
...@@ -26,6 +31,13 @@ class AssistantCacheController : public mojom::VoiceInteractionObserver { ...@@ -26,6 +31,13 @@ class AssistantCacheController : public mojom::VoiceInteractionObserver {
void AddModelObserver(AssistantCacheModelObserver* observer); void AddModelObserver(AssistantCacheModelObserver* observer);
void RemoveModelObserver(AssistantCacheModelObserver* observer); void RemoveModelObserver(AssistantCacheModelObserver* observer);
// AssistantControllerObserver:
void OnAssistantControllerConstructed() override;
void OnAssistantControllerDestroying() override;
// AssistantUiModelObserver:
void OnUiVisibilityChanged(bool visible, AssistantSource source) override;
private: private:
// mojom::VoiceInteractionObserver: // mojom::VoiceInteractionObserver:
void OnVoiceInteractionStatusChanged( void OnVoiceInteractionStatusChanged(
...@@ -39,6 +51,8 @@ class AssistantCacheController : public mojom::VoiceInteractionObserver { ...@@ -39,6 +51,8 @@ class AssistantCacheController : public mojom::VoiceInteractionObserver {
void UpdateConversationStarters(); void UpdateConversationStarters();
AssistantController* const assistant_controller_; // Owned by Shell.
mojo::Binding<mojom::VoiceInteractionObserver> voice_interaction_binding_; mojo::Binding<mojom::VoiceInteractionObserver> voice_interaction_binding_;
AssistantCacheModel model_; AssistantCacheModel model_;
......
...@@ -25,7 +25,8 @@ namespace ash { ...@@ -25,7 +25,8 @@ namespace ash {
AssistantController::AssistantController() AssistantController::AssistantController()
: assistant_volume_control_binding_(this), : assistant_volume_control_binding_(this),
assistant_cache_controller_(std::make_unique<AssistantCacheController>()), assistant_cache_controller_(
std::make_unique<AssistantCacheController>(this)),
assistant_interaction_controller_( assistant_interaction_controller_(
std::make_unique<AssistantInteractionController>(this)), std::make_unique<AssistantInteractionController>(this)),
assistant_notification_controller_( assistant_notification_controller_(
......
...@@ -55,18 +55,25 @@ int SuggestionContainerView::GetHeightForWidth(int width) const { ...@@ -55,18 +55,25 @@ int SuggestionContainerView::GetHeightForWidth(int width) const {
void SuggestionContainerView::OnContentsPreferredSizeChanged( void SuggestionContainerView::OnContentsPreferredSizeChanged(
views::View* content_view) { views::View* content_view) {
const int preferred_width = content_view->GetPreferredSize().width(); // Our contents should never be smaller than our container width because when
content_view->SetSize(gfx::Size(preferred_width, kPreferredHeightDip)); // 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() { void SuggestionContainerView::InitLayout() {
views::BoxLayout* layout_manager = layout_manager_ =
content_view()->SetLayoutManager(std::make_unique<views::BoxLayout>( content_view()->SetLayoutManager(std::make_unique<views::BoxLayout>(
views::BoxLayout::Orientation::kHorizontal, views::BoxLayout::Orientation::kHorizontal,
gfx::Insets(0, kPaddingDip), kSpacingDip)); gfx::Insets(0, kPaddingDip), kSpacingDip));
layout_manager->set_cross_axis_alignment( layout_manager_->set_cross_axis_alignment(
views::BoxLayout::CrossAxisAlignment::CROSS_AXIS_ALIGNMENT_END); 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( void SuggestionContainerView::OnConversationStartersChanged(
...@@ -81,6 +88,11 @@ void SuggestionContainerView::OnResponseChanged( ...@@ -81,6 +88,11 @@ void SuggestionContainerView::OnResponseChanged(
has_received_response_ = true; has_received_response_ = true;
OnSuggestionsCleared(); 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()); OnSuggestionsChanged(response.GetSuggestions());
} }
...@@ -183,6 +195,11 @@ void SuggestionContainerView::OnUiVisibilityChanged(bool visible, ...@@ -183,6 +195,11 @@ void SuggestionContainerView::OnUiVisibilityChanged(bool visible,
} else { } else {
// Reset view state. // Reset view state.
has_received_response_ = false; 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 @@ ...@@ -16,6 +16,10 @@
#include "chromeos/services/assistant/public/mojom/assistant.mojom.h" #include "chromeos/services/assistant/public/mojom/assistant.mojom.h"
#include "ui/views/controls/scroll_view.h" #include "ui/views/controls/scroll_view.h"
namespace views {
class BoxLayout;
} // namespace views
namespace ash { namespace ash {
class AssistantController; class AssistantController;
...@@ -68,6 +72,8 @@ class SuggestionContainerView : public AssistantScrollView, ...@@ -68,6 +72,8 @@ class SuggestionContainerView : public AssistantScrollView,
AssistantController* const assistant_controller_; // Owned by Shell. 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 // 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 // map is the unique identifier by which the Assistant interaction model
// identifies the view's underlying suggestion. // 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