Commit 4ea92f18 authored by Meilin Wang's avatar Meilin Wang Committed by Commit Bot

ambient: prototype a basic UI.

This patch implements a simple functional UI in ambient mode
for further testing and investigation.

Bug: b/139698911
Test: manually.
Change-Id: Iaac9af294afe4d47cd3a7138f56fb2e8c668a634
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1850585
Commit-Queue: Meilin Wang <meilinw@chromium.org>
Reviewed-by: default avatarXiaohui Chen <xiaohuic@chromium.org>
Reviewed-by: default avatarTao Wu <wutao@chromium.org>
Reviewed-by: default avatarXiyuan Xia <xiyuan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#708363}
parent fc59bb21
...@@ -163,8 +163,14 @@ component("ash") { ...@@ -163,8 +163,14 @@ component("ash") {
"ambient/model/photo_model.cc", "ambient/model/photo_model.cc",
"ambient/model/photo_model.h", "ambient/model/photo_model.h",
"ambient/model/photo_model_observer.h", "ambient/model/photo_model_observer.h",
"ambient/ui/ambient_assistant_container_view.cc",
"ambient/ui/ambient_assistant_container_view.h",
"ambient/ui/ambient_assistant_dialog_plate.cc",
"ambient/ui/ambient_assistant_dialog_plate.h",
"ambient/ui/ambient_container_view.cc", "ambient/ui/ambient_container_view.cc",
"ambient/ui/ambient_container_view.h", "ambient/ui/ambient_container_view.h",
"ambient/ui/assistant_response_container_view.cc",
"ambient/ui/assistant_response_container_view.h",
"ambient/ui/photo_view.cc", "ambient/ui/photo_view.cc",
"ambient/ui/photo_view.h", "ambient/ui/photo_view.h",
"ambient/util/ambient_util.cc", "ambient/util/ambient_util.cc",
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include "ash/ambient/model/photo_model_observer.h" #include "ash/ambient/model/photo_model_observer.h"
#include "ash/ambient/ui/ambient_container_view.h" #include "ash/ambient/ui/ambient_container_view.h"
#include "ash/ambient/util/ambient_util.h" #include "ash/ambient/util/ambient_util.h"
#include "ash/assistant/assistant_controller.h"
#include "ash/login/ui/lock_screen.h" #include "ash/login/ui/lock_screen.h"
#include "ash/public/cpp/ambient/photo_controller.h" #include "ash/public/cpp/ambient/photo_controller.h"
#include "chromeos/constants/chromeos_features.h" #include "chromeos/constants/chromeos_features.h"
...@@ -24,7 +25,8 @@ bool CanStartAmbientMode() { ...@@ -24,7 +25,8 @@ bool CanStartAmbientMode() {
} // namespace } // namespace
AmbientController::AmbientController() = default; AmbientController::AmbientController(AssistantController* assistant_controller)
: assistant_controller_(assistant_controller) {}
AmbientController::~AmbientController() { AmbientController::~AmbientController() {
DestroyContainerView(); DestroyContainerView();
...@@ -34,6 +36,11 @@ void AmbientController::OnWidgetDestroying(views::Widget* widget) { ...@@ -34,6 +36,11 @@ void AmbientController::OnWidgetDestroying(views::Widget* widget) {
refresh_timer_.Stop(); refresh_timer_.Stop();
container_view_->GetWidget()->RemoveObserver(this); container_view_->GetWidget()->RemoveObserver(this);
container_view_ = nullptr; container_view_ = nullptr;
// If our widget is being destroyed, Assistant UI is no longer visible.
// If Assistant UI was already closed, this is a no-op.
assistant_controller_->ui_controller()->CloseUi(
AssistantExitPoint::kUnspecified);
} }
void AmbientController::Toggle() { void AmbientController::Toggle() {
...@@ -57,6 +64,13 @@ void AmbientController::Start() { ...@@ -57,6 +64,13 @@ void AmbientController::Start() {
return; return;
} }
// CloseUi to ensure standalone Assistant Ui doesn't exist when entering
// Ambient mode to avoid strange behavior caused by standalone Ui was
// only hidden at that time. This will be a no-op if Ui was already closed.
// TODO(meilinw): Handle embedded Ui.
assistant_controller_->ui_controller()->CloseUi(
AssistantExitPoint::kUnspecified);
CreateContainerView(); CreateContainerView();
container_view_->GetWidget()->Show(); container_view_->GetWidget()->Show();
RefreshImage(); RefreshImage();
......
...@@ -19,12 +19,13 @@ class ImageSkia; ...@@ -19,12 +19,13 @@ class ImageSkia;
namespace ash { namespace ash {
class AmbientContainerView; class AmbientContainerView;
class AssistantController;
class PhotoModelObserver; class PhotoModelObserver;
// Class to handle all ambient mode functionalities. // Class to handle all ambient mode functionalities.
class ASH_EXPORT AmbientController : views::WidgetObserver { class ASH_EXPORT AmbientController : views::WidgetObserver {
public: public:
AmbientController(); explicit AmbientController(AssistantController* assistant_controller);
~AmbientController() override; ~AmbientController() override;
// views::WidgetObserver: // views::WidgetObserver:
...@@ -46,6 +47,10 @@ class ASH_EXPORT AmbientController : views::WidgetObserver { ...@@ -46,6 +47,10 @@ class ASH_EXPORT AmbientController : views::WidgetObserver {
return refresh_timer_; return refresh_timer_;
} }
AssistantController* assistant_controller() { return assistant_controller_; }
bool is_showing() const { return !!container_view_; }
private: private:
void Start(); void Start();
void Stop(); void Stop();
...@@ -56,7 +61,8 @@ class ASH_EXPORT AmbientController : views::WidgetObserver { ...@@ -56,7 +61,8 @@ class ASH_EXPORT AmbientController : views::WidgetObserver {
void GetNextImage(); void GetNextImage();
void OnPhotoDownloaded(const gfx::ImageSkia& image); void OnPhotoDownloaded(const gfx::ImageSkia& image);
AmbientContainerView* container_view_ = nullptr; AssistantController* const assistant_controller_; // Owned by Shell.
AmbientContainerView* container_view_ = nullptr; // Owned by view hierarchy.
PhotoModel model_; PhotoModel model_;
base::OneShotTimer refresh_timer_; base::OneShotTimer refresh_timer_;
base::WeakPtrFactory<AmbientController> weak_factory_{this}; base::WeakPtrFactory<AmbientController> weak_factory_{this};
......
// Copyright 2019 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/ambient/ui/ambient_assistant_container_view.h"
#include <memory>
#include <string>
#include "ash/ambient/ui/ambient_assistant_dialog_plate.h"
#include "ash/ambient/ui/assistant_response_container_view.h"
#include "ash/assistant/ui/assistant_ui_constants.h"
#include "ash/assistant/ui/assistant_view_delegate.h"
#include "ash/assistant/util/assistant_util.h"
#include "ash/session/session_controller_impl.h"
#include "ash/shell.h"
#include "ash/strings/grit/ash_strings.h"
#include "base/strings/utf_string_conversions.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/views/background.h"
#include "ui/views/controls/image_view.h"
#include "ui/views/controls/label.h"
#include "ui/views/layout/box_layout.h"
namespace ash {
namespace {
// Appearance.
constexpr int kAvatarImageSizeDip = 32;
// Greeting message.
base::string16 GetGreetingMessage(const UserSession* user_session) {
const std::string& username = user_session->user_info.display_name;
return l10n_util::GetStringFUTF16(IDS_ASSISTANT_AMBIENT_GREETING_MESSAGE,
base::UTF8ToUTF16(username));
}
} // namespace
AmbientAssistantContainerView::AmbientAssistantContainerView(
AssistantViewDelegate* delegate)
: delegate_(delegate) {
InitLayout();
// The AssistantViewDelegate should outlive AmbientAssistantContainerView.
delegate_->AddUiModelObserver(this);
}
AmbientAssistantContainerView::~AmbientAssistantContainerView() {
delegate_->RemoveUiModelObserver(this);
}
const char* AmbientAssistantContainerView::GetClassName() const {
return "AmbientAssistantContainerView";
}
void AmbientAssistantContainerView::OnUiVisibilityChanged(
AssistantVisibility new_visibility,
AssistantVisibility old_visibility,
base::Optional<AssistantEntryPoint> entry_point,
base::Optional<AssistantExitPoint> exit_point) {
// TODO(meilinw): Define the expected behavior where multiple Assistant UIs
// could exist at the same time (e.g. launcher embedded UI and ambient UI
// for in-session Ambient Mode), but only one that is currently active
// should be responding to Assistant events.
if (assistant::util::IsStartingSession(new_visibility, old_visibility))
SetVisible(true);
else if (assistant::util::IsFinishingSession(new_visibility))
SetVisible(false);
}
void AmbientAssistantContainerView::InitLayout() {
SetPaintToLayer();
SetBackground(views::CreateSolidBackground(SK_ColorWHITE));
constexpr int kRightPaddingDip = 8;
views::BoxLayout* layout_manager =
SetLayoutManager(std::make_unique<views::BoxLayout>(
views::BoxLayout::Orientation::kHorizontal,
gfx::Insets(0, 0, 0, kRightPaddingDip)));
layout_manager->set_cross_axis_alignment(
views::BoxLayout::CrossAxisAlignment::kCenter);
// Mic button and input query view.
ambient_assistant_dialog_plate_ =
AddChildView(std::make_unique<AmbientAssistantDialogPlate>(delegate_));
// Response container view.
assistant_response_container_view_ =
AddChildView(std::make_unique<AssistantResponseContainerView>(delegate_));
// Greeting label.
const UserSession* active_user_session =
Shell::Get()->session_controller()->GetUserSession(0);
greeting_label_ = AddChildView(
std::make_unique<views::Label>(GetGreetingMessage(active_user_session)));
greeting_label_->SetEnabledColor(kTextColorSecondary);
greeting_label_->SetFontList(
ash::assistant::ui::GetDefaultFontList()
.DeriveWithSizeDelta(8)
.DeriveWithWeight(gfx::Font::Weight::NORMAL));
greeting_label_->SetHorizontalAlignment(
gfx::HorizontalAlignment::ALIGN_CENTER);
// Spacer.
views::View* spacer = AddChildView(std::make_unique<views::View>());
// Sets the flex weight to be 1 so the spacer view can be resized.
layout_manager->SetFlexForView(spacer, 1);
// Rounded avatar image view.
avatar_view_ = AddChildView(std::make_unique<views::ImageView>());
avatar_view_->SetImageSize(
gfx::Size(kAvatarImageSizeDip, kAvatarImageSizeDip));
avatar_view_->SetPreferredSize(
gfx::Size(kAvatarImageSizeDip, kAvatarImageSizeDip));
gfx::ImageSkia avatar = active_user_session->user_info.avatar.image;
if (!avatar.isNull())
avatar_view_->SetImage(avatar);
SkPath circular_mask;
constexpr int kClipCircleRadius = kAvatarImageSizeDip / 2;
circular_mask.addCircle(kClipCircleRadius, kClipCircleRadius,
kClipCircleRadius);
avatar_view_->set_clip_path(circular_mask);
}
} // namespace ash
// Copyright 2019 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.
#ifndef ASH_AMBIENT_UI_AMBIENT_ASSISTANT_CONTAINER_VIEW_H_
#define ASH_AMBIENT_UI_AMBIENT_ASSISTANT_CONTAINER_VIEW_H_
#include "ash/assistant/model/assistant_ui_model_observer.h"
#include "base/macros.h"
#include "ui/views/view.h"
namespace views {
class ImageView;
class Label;
} // namespace views
namespace ash {
class AssistantResponseContainerView;
class AssistantViewDelegate;
class AmbientAssistantDialogPlate;
class AmbientAssistantContainerView : public views::View,
public AssistantUiModelObserver {
public:
explicit AmbientAssistantContainerView(AssistantViewDelegate* delegate);
~AmbientAssistantContainerView() override;
// views::View:
const char* GetClassName() const override;
// AssistantUiModelObserver:
void OnUiVisibilityChanged(
AssistantVisibility new_visibility,
AssistantVisibility old_visibility,
base::Optional<AssistantEntryPoint> entry_point,
base::Optional<AssistantExitPoint> exit_point) override;
private:
void InitLayout();
AssistantViewDelegate* const delegate_; // Owned by AssistantController.
// Owned by view hierarchy.
AmbientAssistantDialogPlate* ambient_assistant_dialog_plate_ = nullptr;
AssistantResponseContainerView* assistant_response_container_view_ = nullptr;
views::ImageView* avatar_view_ = nullptr;
views::Label* greeting_label_ = nullptr;
DISALLOW_COPY_AND_ASSIGN(AmbientAssistantContainerView);
};
} // namespace ash
#endif // ASH_AMBIENT_UI_AMBIENT_ASSISTANT_CONTAINER_VIEW_H_
// Copyright 2019 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/ambient/ui/ambient_assistant_dialog_plate.h"
#include <memory>
#include "ash/assistant/ui/assistant_view_delegate.h"
#include "ash/assistant/ui/dialog_plate/mic_view.h"
#include "ash/assistant/ui/main_stage/assistant_query_view.h"
#include "ash/strings/grit/ash_strings.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/views/layout/box_layout.h"
namespace ash {
AmbientAssistantDialogPlate::AmbientAssistantDialogPlate(
AssistantViewDelegate* delegate)
: delegate_(delegate) {
InitLayout();
// The AssistantViewDelegate should outlive AmbientAssistantDialogPlate.
delegate_->AddInteractionModelObserver(this);
}
AmbientAssistantDialogPlate::~AmbientAssistantDialogPlate() {
delegate_->RemoveInteractionModelObserver(this);
}
const char* AmbientAssistantDialogPlate::GetClassName() const {
return "AmbientAssistantDialogPlate";
}
void AmbientAssistantDialogPlate::ButtonPressed(views::Button* sender,
const ui::Event& event) {
delegate_->OnDialogPlateButtonPressed(
static_cast<AssistantButtonId>(sender->GetID()));
}
void AmbientAssistantDialogPlate::OnCommittedQueryChanged(
const AssistantQuery& query) {
voice_query_view_->SetQuery(query);
}
void AmbientAssistantDialogPlate::OnPendingQueryChanged(
const AssistantQuery& query) {
voice_query_view_->SetQuery(query);
}
void AmbientAssistantDialogPlate::InitLayout() {
views::BoxLayout* layout_manager =
SetLayoutManager(std::make_unique<views::BoxLayout>(
views::BoxLayout::Orientation::kHorizontal));
layout_manager->set_main_axis_alignment(
views::BoxLayout::MainAxisAlignment::kStart);
// Animated voice input toggle button.
animated_voice_input_toggle_ = AddChildView(std::make_unique<MicView>(
this, delegate_, AssistantButtonId::kVoiceInputToggle));
animated_voice_input_toggle_->SetAccessibleName(
l10n_util::GetStringUTF16(IDS_ASH_ASSISTANT_DIALOG_PLATE_MIC_ACCNAME));
// Voice input query view.
voice_query_view_ = AddChildView(std::make_unique<AssistantQueryView>());
}
} // namespace ash
// Copyright 2019 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.
#ifndef ASH_AMBIENT_UI_AMBIENT_ASSISTANT_DIALOG_PLATE_H_
#define ASH_AMBIENT_UI_AMBIENT_ASSISTANT_DIALOG_PLATE_H_
#include "ash/assistant/model/assistant_interaction_model_observer.h"
#include "base/macros.h"
#include "ui/views/controls/button/button.h"
#include "ui/views/view.h"
namespace ash {
class AssistantQueryView;
class AssistantViewDelegate;
class MicView;
enum class AssistantButtonId;
class AmbientAssistantDialogPlate : public views::View,
public views::ButtonListener,
public AssistantInteractionModelObserver {
public:
explicit AmbientAssistantDialogPlate(AssistantViewDelegate* delegate);
~AmbientAssistantDialogPlate() override;
// views::View:
const char* GetClassName() const override;
// views::ButtonListener:
void ButtonPressed(views::Button* sender, const ui::Event& event) override;
// AssistantInteractionModelObserver:
void OnCommittedQueryChanged(const AssistantQuery& query) override;
void OnPendingQueryChanged(const AssistantQuery& query) override;
private:
void InitLayout();
AssistantViewDelegate* const delegate_;
// Owned by view hierarchy.
MicView* animated_voice_input_toggle_ = nullptr;
AssistantQueryView* voice_query_view_ = nullptr;
DISALLOW_COPY_AND_ASSIGN(AmbientAssistantDialogPlate);
};
} // namespace ash
#endif // ASH_AMBIENT_UI_AMBIENT_ASSISTANT_DIALOG_PLATE_H_
...@@ -4,10 +4,14 @@ ...@@ -4,10 +4,14 @@
#include "ash/ambient/ui/ambient_container_view.h" #include "ash/ambient/ui/ambient_container_view.h"
#include <memory>
#include <utility>
#include "ash/ambient/ambient_controller.h" #include "ash/ambient/ambient_controller.h"
#include "ash/ambient/ui/ambient_container_view.h" #include "ash/ambient/ui/ambient_assistant_container_view.h"
#include "ash/ambient/ui/photo_view.h" #include "ash/ambient/ui/photo_view.h"
#include "ash/ambient/util/ambient_util.h" #include "ash/ambient/util/ambient_util.h"
#include "ash/assistant/assistant_controller.h"
#include "ash/login/ui/lock_screen.h" #include "ash/login/ui/lock_screen.h"
#include "ash/public/cpp/shell_window_ids.h" #include "ash/public/cpp/shell_window_ids.h"
#include "ash/shell.h" #include "ash/shell.h"
...@@ -20,6 +24,9 @@ namespace ash { ...@@ -20,6 +24,9 @@ namespace ash {
namespace { namespace {
// Ambient Assistant container view appearance.
constexpr int kAmbientAssistantContainerViewPreferredHeightDip = 128;
aura::Window* GetContainer() { aura::Window* GetContainer() {
aura::Window* container = nullptr; aura::Window* container = nullptr;
if (ambient::util::IsShowing(LockScreen::ScreenType::kLock)) if (ambient::util::IsShowing(LockScreen::ScreenType::kLock))
...@@ -60,6 +67,16 @@ gfx::Size AmbientContainerView::CalculatePreferredSize() const { ...@@ -60,6 +67,16 @@ gfx::Size AmbientContainerView::CalculatePreferredSize() const {
return GetWidget()->GetNativeWindow()->GetRootWindow()->bounds().size(); return GetWidget()->GetNativeWindow()->GetRootWindow()->bounds().size();
} }
void AmbientContainerView::Layout() {
if (!ambient_assistant_container_view_)
return;
// Set bounds for the ambient Assistant container view.
ambient_assistant_container_view_->SetBoundsRect(
gfx::Rect(0, 0, GetWidget()->GetRootView()->size().width(),
kAmbientAssistantContainerViewPreferredHeightDip));
}
void AmbientContainerView::OnMouseEvent(ui::MouseEvent* event) { void AmbientContainerView::OnMouseEvent(ui::MouseEvent* event) {
if (event->type() == ui::ET_MOUSE_PRESSED) { if (event->type() == ui::ET_MOUSE_PRESSED) {
event->SetHandled(); event->SetHandled();
...@@ -79,8 +96,12 @@ void AmbientContainerView::Init() { ...@@ -79,8 +96,12 @@ void AmbientContainerView::Init() {
// TODO(b/139954108): Choose a better dark mode theme color. // TODO(b/139954108): Choose a better dark mode theme color.
SetBackground(views::CreateSolidBackground(SK_ColorBLACK)); SetBackground(views::CreateSolidBackground(SK_ColorBLACK));
photo_view_ = new PhotoView(ambient_controller_); photo_view_ = AddChildView(std::make_unique<PhotoView>(ambient_controller_));
AddChildView(photo_view_);
ambient_assistant_container_view_ =
AddChildView(std::make_unique<AmbientAssistantContainerView>(
ambient_controller_->assistant_controller()->view_delegate()));
ambient_assistant_container_view_->SetVisible(false);
} }
} // namespace ash } // namespace ash
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
namespace ash { namespace ash {
class AmbientAssistantContainerView;
class AmbientController; class AmbientController;
class PhotoView; class PhotoView;
...@@ -23,6 +24,7 @@ class ASH_EXPORT AmbientContainerView : public views::WidgetDelegateView { ...@@ -23,6 +24,7 @@ class ASH_EXPORT AmbientContainerView : public views::WidgetDelegateView {
// views::View: // views::View:
const char* GetClassName() const override; const char* GetClassName() const override;
gfx::Size CalculatePreferredSize() const override; gfx::Size CalculatePreferredSize() const override;
void Layout() override;
void OnMouseEvent(ui::MouseEvent* event) override; void OnMouseEvent(ui::MouseEvent* event) override;
void OnGestureEvent(ui::GestureEvent* event) override; void OnGestureEvent(ui::GestureEvent* event) override;
...@@ -30,7 +32,10 @@ class ASH_EXPORT AmbientContainerView : public views::WidgetDelegateView { ...@@ -30,7 +32,10 @@ class ASH_EXPORT AmbientContainerView : public views::WidgetDelegateView {
void Init(); void Init();
AmbientController* ambient_controller_ = nullptr; AmbientController* ambient_controller_ = nullptr;
PhotoView* photo_view_ = nullptr; // Owned by view hierarchy.
// Owned by view hierarchy.
PhotoView* photo_view_ = nullptr;
AmbientAssistantContainerView* ambient_assistant_container_view_ = nullptr;
DISALLOW_COPY_AND_ASSIGN(AmbientContainerView); DISALLOW_COPY_AND_ASSIGN(AmbientContainerView);
}; };
......
// Copyright 2019 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/ambient/ui/assistant_response_container_view.h"
#include <memory>
#include "ash/assistant/model/assistant_interaction_model_observer.h"
#include "ash/assistant/model/assistant_response.h"
#include "ash/assistant/model/assistant_ui_element.h"
#include "ash/assistant/ui/assistant_view_delegate.h"
#include "ash/assistant/ui/main_stage/assistant_text_element_view.h"
#include "ui/views/layout/box_layout.h"
namespace ash {
namespace {
// Appearance.
constexpr int kPreferredWidthDip = 600;
} // namespace
AssistantResponseContainerView::AssistantResponseContainerView(
AssistantViewDelegate* delegate)
: AnimatedContainerView(delegate) {
InitLayout();
}
AssistantResponseContainerView::~AssistantResponseContainerView() = default;
const char* AssistantResponseContainerView::GetClassName() const {
return "AssistantResponseContainerView";
}
gfx::Size AssistantResponseContainerView::CalculatePreferredSize() const {
return gfx::Size(kPreferredWidthDip,
content_view()->GetHeightForWidth(kPreferredWidthDip));
}
void AssistantResponseContainerView::OnContentsPreferredSizeChanged(
views::View* content_view) {
content_view->SetSize(CalculatePreferredSize());
}
void AssistantResponseContainerView::InitLayout() {
content_view()->SetLayoutManager(std::make_unique<views::BoxLayout>(
views::BoxLayout::Orientation::kVertical));
}
void AssistantResponseContainerView::HandleResponse(
const AssistantResponse& response) {
for (const auto& ui_element : response.GetUiElements()) {
switch (ui_element->GetType()) {
case AssistantUiElementType::kCard:
// For card elements, we instead use the "fallback" message for HTML
// card rendering as the text response.
AddTextElementView(new AssistantTextElement(
static_cast<const AssistantCardElement*>(ui_element.get())
->fallback()));
break;
case AssistantUiElementType::kText:
AddTextElementView(
static_cast<const AssistantTextElement*>(ui_element.get()));
break;
}
}
}
void AssistantResponseContainerView::AddTextElementView(
const AssistantTextElement* text_element) {
content_view()->AddChildView(
std::make_unique<AssistantTextElementView>(text_element));
}
} // namespace ash
// Copyright 2019 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.
#ifndef ASH_AMBIENT_UI_ASSISTANT_RESPONSE_CONTAINER_VIEW_H_
#define ASH_AMBIENT_UI_ASSISTANT_RESPONSE_CONTAINER_VIEW_H_
#include "ash/assistant/ui/main_stage/animated_container_view.h"
#include "base/macros.h"
namespace ash {
class AssistantResponse;
class AssistantTextElement;
class AssistantViewDelegate;
class AssistantResponseContainerView : public AnimatedContainerView {
public:
explicit AssistantResponseContainerView(AssistantViewDelegate* delegate);
~AssistantResponseContainerView() override;
// AnimatedContainerView:
const char* GetClassName() const override;
gfx::Size CalculatePreferredSize() const override;
void OnContentsPreferredSizeChanged(views::View* content_view) override;
private:
void InitLayout();
void AddTextElementView(const AssistantTextElement* text_element);
// AnimatedContainerView:
void HandleResponse(const AssistantResponse& response) override;
DISALLOW_COPY_AND_ASSIGN(AssistantResponseContainerView);
};
} // namespace ash
#endif // ASH_AMBIENT_UI_ASSISTANT_RESPONSE_CONTAINER_VIEW_H_
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#include "ash/app_list/views/assistant/assistant_page_view.h" #include "ash/app_list/views/assistant/assistant_page_view.h"
#include <algorithm>
#include <memory> #include <memory>
#include <utility> #include <utility>
...@@ -139,6 +140,7 @@ void AssistantPageView::RequestFocus() { ...@@ -139,6 +140,7 @@ void AssistantPageView::RequestFocus() {
} }
NOTREACHED(); NOTREACHED();
break; break;
case AssistantUiMode::kAmbientUi:
case AssistantUiMode::kMainUi: case AssistantUiMode::kMainUi:
case AssistantUiMode::kMiniUi: case AssistantUiMode::kMiniUi:
NOTREACHED(); NOTREACHED();
...@@ -259,6 +261,7 @@ void AssistantPageView::OnUiModeChanged(AssistantUiMode ui_mode, ...@@ -259,6 +261,7 @@ void AssistantPageView::OnUiModeChanged(AssistantUiMode ui_mode,
} }
NOTREACHED(); NOTREACHED();
break; break;
case AssistantUiMode::kAmbientUi:
case AssistantUiMode::kMainUi: case AssistantUiMode::kMainUi:
case AssistantUiMode::kMiniUi: case AssistantUiMode::kMiniUi:
NOTREACHED(); NOTREACHED();
...@@ -310,6 +313,7 @@ int AssistantPageView::GetChildViewHeightForWidth(int width) const { ...@@ -310,6 +313,7 @@ int AssistantPageView::GetChildViewHeightForWidth(int width) const {
} }
NOTREACHED(); NOTREACHED();
break; break;
case AssistantUiMode::kAmbientUi:
case AssistantUiMode::kMainUi: case AssistantUiMode::kMainUi:
case AssistantUiMode::kMiniUi: case AssistantUiMode::kMiniUi:
NOTREACHED(); NOTREACHED();
......
...@@ -2023,6 +2023,9 @@ This file contains the strings for ash. ...@@ -2023,6 +2023,9 @@ This file contains the strings for ash.
<message name="IDS_ASSISTANT_EDIT_REMINDER_QUERY" desc="Query to issue to edit reminder."> <message name="IDS_ASSISTANT_EDIT_REMINDER_QUERY" desc="Query to issue to edit reminder.">
Edit reminder Edit reminder
</message> </message>
<message name="IDS_ASSISTANT_AMBIENT_GREETING_MESSAGE" desc="Greetings message shown on Ambient Mode UI.">
Hi, <ph name="USERNAME">$1</ph>
</message>
<message name="IDS_ASH_MESSAGE_CENTER_UNLOCK_TO_PERFORM_ACTION" desc="The short message to encourage user to unlock the device so that Chrome OS can perform the notification action selected by user after unlocking."> <message name="IDS_ASH_MESSAGE_CENTER_UNLOCK_TO_PERFORM_ACTION" desc="The short message to encourage user to unlock the device so that Chrome OS can perform the notification action selected by user after unlocking.">
Unlock device to perform the notification action Unlock device to perform the notification action
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#include "ash/assistant/assistant_ui_controller.h" #include "ash/assistant/assistant_ui_controller.h"
#include "ash/ambient/ambient_controller.h"
#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_screen_context_controller.h" #include "ash/assistant/assistant_screen_context_controller.h"
...@@ -26,6 +27,7 @@ ...@@ -26,6 +27,7 @@
#include "ash/system/toast/toast_manager_impl.h" #include "ash/system/toast/toast_manager_impl.h"
#include "base/bind.h" #include "base/bind.h"
#include "base/optional.h" #include "base/optional.h"
#include "chromeos/constants/chromeos_features.h"
#include "chromeos/services/assistant/public/features.h" #include "chromeos/services/assistant/public/features.h"
#include "chromeos/services/assistant/public/mojom/assistant.mojom.h" #include "chromeos/services/assistant/public/mojom/assistant.mojom.h"
#include "ui/aura/client/aura_constants.h" #include "ui/aura/client/aura_constants.h"
...@@ -468,7 +470,8 @@ void AssistantUiController::OnUiVisibilityChanged( ...@@ -468,7 +470,8 @@ void AssistantUiController::OnUiVisibilityChanged(
assistant::util::RecordAssistantEntryPoint(entry_point.value()); assistant::util::RecordAssistantEntryPoint(entry_point.value());
if (!container_view_) { if (!container_view_) {
DCHECK_EQ(AssistantUiMode::kLauncherEmbeddedUi, model_.ui_mode()); DCHECK(model_.ui_mode() == AssistantUiMode::kAmbientUi ||
model_.ui_mode() == AssistantUiMode::kLauncherEmbeddedUi);
event_monitor_.reset(); event_monitor_.reset();
break; break;
} }
...@@ -534,6 +537,13 @@ void AssistantUiController::ShowUi(AssistantEntryPoint entry_point) { ...@@ -534,6 +537,13 @@ void AssistantUiController::ShowUi(AssistantEntryPoint entry_point) {
return; return;
} }
if (chromeos::features::IsAmbientModeEnabled() &&
Shell::Get()->ambient_controller()->is_showing()) {
model_.SetUiMode(AssistantUiMode::kAmbientUi);
model_.SetVisible(entry_point);
return;
}
if (app_list_features::IsEmbeddedAssistantUIEnabled()) { if (app_list_features::IsEmbeddedAssistantUIEnabled()) {
model_.SetUiMode(AssistantUiMode::kLauncherEmbeddedUi); model_.SetUiMode(AssistantUiMode::kLauncherEmbeddedUi);
model_.SetVisible(entry_point); model_.SetVisible(entry_point);
...@@ -541,6 +551,7 @@ void AssistantUiController::ShowUi(AssistantEntryPoint entry_point) { ...@@ -541,6 +551,7 @@ void AssistantUiController::ShowUi(AssistantEntryPoint entry_point) {
} }
DCHECK_NE(AssistantUiMode::kLauncherEmbeddedUi, model_.ui_mode()); DCHECK_NE(AssistantUiMode::kLauncherEmbeddedUi, model_.ui_mode());
DCHECK_NE(AssistantUiMode::kAmbientUi, model_.ui_mode());
if (model_.visibility() == AssistantVisibility::kVisible) { if (model_.visibility() == AssistantVisibility::kVisible) {
// If Assistant window is already visible, we just try to retake focus. // If Assistant window is already visible, we just try to retake focus.
......
...@@ -57,10 +57,11 @@ enum class AssistantExitPoint { ...@@ -57,10 +57,11 @@ enum class AssistantExitPoint {
// Enumeration of Assistant UI modes. // Enumeration of Assistant UI modes.
enum class AssistantUiMode { enum class AssistantUiMode {
kAmbientUi,
kLauncherEmbeddedUi,
kMainUi, kMainUi,
kMiniUi, kMiniUi,
kWebUi, kWebUi,
kLauncherEmbeddedUi,
}; };
// Enumeration of Assistant visibility states. // Enumeration of Assistant visibility states.
......
...@@ -365,6 +365,7 @@ void AssistantContainerView::RequestFocus() { ...@@ -365,6 +365,7 @@ void AssistantContainerView::RequestFocus() {
if (assistant_web_view_) if (assistant_web_view_)
assistant_web_view_->RequestFocus(); assistant_web_view_->RequestFocus();
break; break;
case AssistantUiMode::kAmbientUi:
case AssistantUiMode::kLauncherEmbeddedUi: case AssistantUiMode::kLauncherEmbeddedUi:
NOTREACHED(); NOTREACHED();
break; break;
...@@ -397,6 +398,7 @@ void AssistantContainerView::OnUiModeChanged(AssistantUiMode ui_mode, ...@@ -397,6 +398,7 @@ void AssistantContainerView::OnUiModeChanged(AssistantUiMode ui_mode,
case AssistantUiMode::kWebUi: case AssistantUiMode::kWebUi:
assistant_web_view_->SetVisible(true); assistant_web_view_->SetVisible(true);
break; break;
case AssistantUiMode::kAmbientUi:
case AssistantUiMode::kLauncherEmbeddedUi: case AssistantUiMode::kLauncherEmbeddedUi:
NOTREACHED(); NOTREACHED();
break; break;
...@@ -430,6 +432,7 @@ views::View* AssistantContainerView::FindFirstFocusableView() { ...@@ -430,6 +432,7 @@ views::View* AssistantContainerView::FindFirstFocusableView() {
case AssistantUiMode::kWebUi: case AssistantUiMode::kWebUi:
// Default views::FocusSearch behavior is acceptable. // Default views::FocusSearch behavior is acceptable.
return nullptr; return nullptr;
case AssistantUiMode::kAmbientUi:
case AssistantUiMode::kLauncherEmbeddedUi: case AssistantUiMode::kLauncherEmbeddedUi:
NOTREACHED(); NOTREACHED();
return nullptr; return nullptr;
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#define ASH_ASSISTANT_UI_MAIN_STAGE_ANIMATED_CONTAINER_VIEW_H_ #define ASH_ASSISTANT_UI_MAIN_STAGE_ANIMATED_CONTAINER_VIEW_H_
#include <memory> #include <memory>
#include <vector>
#include "ash/assistant/model/assistant_interaction_model_observer.h" #include "ash/assistant/model/assistant_interaction_model_observer.h"
#include "ash/assistant/ui/base/assistant_scroll_view.h" #include "ash/assistant/ui/base/assistant_scroll_view.h"
...@@ -46,7 +47,8 @@ class ElementAnimator; ...@@ -46,7 +47,8 @@ class ElementAnimator;
// all |ElementAnimator| instances. // all |ElementAnimator| instances.
// 8) Finally when this animation is complete the derived class is informed // 8) Finally when this animation is complete the derived class is informed
// through |AnimatedContainerView::OnAllViewsAnimatedIn|. // through |AnimatedContainerView::OnAllViewsAnimatedIn|.
class AnimatedContainerView : public AssistantScrollView, class COMPONENT_EXPORT(ASSISTANT_UI) AnimatedContainerView
: public AssistantScrollView,
public AssistantInteractionModelObserver { public AssistantInteractionModelObserver {
public: public:
explicit AnimatedContainerView(AssistantViewDelegate* delegate); explicit AnimatedContainerView(AssistantViewDelegate* delegate);
......
...@@ -237,9 +237,7 @@ UiElementContainerView::UiElementContainerView(AssistantViewDelegate* delegate) ...@@ -237,9 +237,7 @@ UiElementContainerView::UiElementContainerView(AssistantViewDelegate* delegate)
InitLayout(); InitLayout();
} }
UiElementContainerView::~UiElementContainerView() { UiElementContainerView::~UiElementContainerView() = default;
delegate()->RemoveInteractionModelObserver(this);
}
const char* UiElementContainerView::GetClassName() const { const char* UiElementContainerView::GetClassName() const {
return "UiElementContainerView"; return "UiElementContainerView";
......
...@@ -1044,8 +1044,10 @@ void Shell::Init( ...@@ -1044,8 +1044,10 @@ void Shell::Init(
// |assistant_controller_| is put before |ambient_controller_| as it will be // |assistant_controller_| is put before |ambient_controller_| as it will be
// used by the latter. // used by the latter.
if (chromeos::features::IsAmbientModeEnabled()) if (chromeos::features::IsAmbientModeEnabled()) {
ambient_controller_ = std::make_unique<AmbientController>(); ambient_controller_ =
std::make_unique<AmbientController>(assistant_controller_.get());
}
home_screen_controller_ = std::make_unique<HomeScreenController>(); home_screen_controller_ = std::make_unique<HomeScreenController>();
......
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