Commit 7ffd284f authored by David Black's avatar David Black Committed by Commit Bot

Download icons for suggestion chips.

The basic strategy is as follows:
- Assistant UI creates suggestion chip w/ icon placeholder.
- Assistant UI requests icon download from AssistantController.
- AssistantController requests download from AssistantImageDownloader.
- AssistantImageDownloader downloads image using BitmapFetcher.
- On success, AssistantImageDownloader runs callback to Assistant UI.
- Assistant UI updates icon for suggestion chip view.

This is a similar flow to what is currently done for rendering
Assistant cards. The BitmapFetcher logic is modeled on what is
currently done by AccountAvatarFetcher.

See bug for demo.

Bug: b:79599200
Change-Id: I9ee09a2458ce955a5e4926fcef43864a05e4454e
Reviewed-on: https://chromium-review.googlesource.com/1066179Reviewed-by: default avatarXiaohui Chen <xiaohuic@chromium.org>
Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Reviewed-by: default avatarXiyuan Xia <xiyuan@chromium.org>
Commit-Queue: David Black <dmblack@google.com>
Cr-Commit-Position: refs/heads/master@{#561724}
parent 29b93df1
...@@ -77,6 +77,11 @@ void AssistantController::SetAssistantCardRenderer( ...@@ -77,6 +77,11 @@ void AssistantController::SetAssistantCardRenderer(
assistant_card_renderer_ = std::move(assistant_card_renderer); assistant_card_renderer_ = std::move(assistant_card_renderer);
} }
void AssistantController::SetAssistantImageDownloader(
mojom::AssistantImageDownloaderPtr assistant_image_downloader) {
assistant_image_downloader_ = std::move(assistant_image_downloader);
}
void AssistantController::RequestScreenshot( void AssistantController::RequestScreenshot(
const gfx::Rect& rect, const gfx::Rect& rect,
RequestScreenshotCallback callback) { RequestScreenshotCallback callback) {
...@@ -110,7 +115,6 @@ void AssistantController::RenderCard( ...@@ -110,7 +115,6 @@ void AssistantController::RenderCard(
} }
AccountId account_id = user_session->user_info->account_id; AccountId account_id = user_session->user_info->account_id;
assistant_card_renderer_->Render(account_id, id_token, std::move(params), assistant_card_renderer_->Render(account_id, id_token, std::move(params),
std::move(callback)); std::move(callback));
} }
...@@ -126,6 +130,23 @@ void AssistantController::ReleaseCards( ...@@ -126,6 +130,23 @@ void AssistantController::ReleaseCards(
assistant_card_renderer_->ReleaseAll(id_tokens); assistant_card_renderer_->ReleaseAll(id_tokens);
} }
void AssistantController::DownloadImage(
const GURL& url,
mojom::AssistantImageDownloader::DownloadCallback callback) {
DCHECK(assistant_image_downloader_);
const mojom::UserSession* user_session =
Shell::Get()->session_controller()->GetUserSession(0);
if (!user_session) {
LOG(WARNING) << "Unable to retrieve active user session.";
return;
}
AccountId account_id = user_session->user_info->account_id;
assistant_image_downloader_->Download(account_id, url, std::move(callback));
}
void AssistantController::AddInteractionModelObserver( void AssistantController::AddInteractionModelObserver(
AssistantInteractionModelObserver* observer) { AssistantInteractionModelObserver* observer) {
assistant_interaction_model_.AddObserver(observer); assistant_interaction_model_.AddObserver(observer);
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include "ash/highlighter/highlighter_controller.h" #include "ash/highlighter/highlighter_controller.h"
#include "ash/public/interfaces/assistant_card_renderer.mojom.h" #include "ash/public/interfaces/assistant_card_renderer.mojom.h"
#include "ash/public/interfaces/assistant_controller.mojom.h" #include "ash/public/interfaces/assistant_controller.mojom.h"
#include "ash/public/interfaces/assistant_image_downloader.mojom.h"
#include "base/macros.h" #include "base/macros.h"
#include "chromeos/services/assistant/public/mojom/assistant.mojom.h" #include "chromeos/services/assistant/public/mojom/assistant.mojom.h"
#include "mojo/public/cpp/bindings/binding.h" #include "mojo/public/cpp/bindings/binding.h"
...@@ -73,6 +74,13 @@ class AssistantController ...@@ -73,6 +74,13 @@ class AssistantController
// Releases resources for any card uniquely identified in |id_token_list|. // Releases resources for any card uniquely identified in |id_token_list|.
void ReleaseCards(const std::vector<base::UnguessableToken>& id_tokens); void ReleaseCards(const std::vector<base::UnguessableToken>& id_tokens);
// Downloads the image found at the specified |url|. On completion, the
// supplied |callback| will be run with the downloaded image. If the download
// attempt is unsuccessful, a NULL image is returned.
void DownloadImage(
const GURL& url,
mojom::AssistantImageDownloader::DownloadCallback callback);
// Invoke to modify the Assistant interaction state. // Invoke to modify the Assistant interaction state.
void StartInteraction(); void StartInteraction();
void StopInteraction(); void StopInteraction();
...@@ -119,6 +127,8 @@ class AssistantController ...@@ -119,6 +127,8 @@ class AssistantController
chromeos::assistant::mojom::AssistantPtr assistant) override; chromeos::assistant::mojom::AssistantPtr assistant) override;
void SetAssistantCardRenderer( void SetAssistantCardRenderer(
mojom::AssistantCardRendererPtr assistant_card_renderer) override; mojom::AssistantCardRendererPtr assistant_card_renderer) override;
void SetAssistantImageDownloader(
mojom::AssistantImageDownloaderPtr assistant_image_downloader) override;
void RequestScreenshot(const gfx::Rect& rect, void RequestScreenshot(const gfx::Rect& rect,
RequestScreenshotCallback callback) override; RequestScreenshotCallback callback) override;
void OnCardPressed(const GURL& url) override; void OnCardPressed(const GURL& url) override;
...@@ -131,6 +141,7 @@ class AssistantController ...@@ -131,6 +141,7 @@ class AssistantController
chromeos::assistant::mojom::AssistantPtr assistant_; chromeos::assistant::mojom::AssistantPtr assistant_;
mojom::AssistantCardRendererPtr assistant_card_renderer_; mojom::AssistantCardRendererPtr assistant_card_renderer_;
mojom::AssistantImageDownloaderPtr assistant_image_downloader_;
std::unique_ptr<AssistantBubble> assistant_bubble_; std::unique_ptr<AssistantBubble> assistant_bubble_;
......
...@@ -7,10 +7,7 @@ ...@@ -7,10 +7,7 @@
#include <memory> #include <memory>
#include "ash/assistant/assistant_controller.h" #include "ash/assistant/assistant_controller.h"
#include "ash/resources/vector_icons/vector_icons.h"
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
#include "ui/gfx/color_palette.h"
#include "ui/gfx/paint_vector_icon.h"
#include "ui/views/controls/scrollbar/overlay_scroll_bar.h" #include "ui/views/controls/scrollbar/overlay_scroll_bar.h"
#include "ui/views/layout/box_layout.h" #include "ui/views/layout/box_layout.h"
...@@ -47,7 +44,8 @@ class InvisibleScrollBar : public views::OverlayScrollBar { ...@@ -47,7 +44,8 @@ class InvisibleScrollBar : public views::OverlayScrollBar {
SuggestionContainerView::SuggestionContainerView( SuggestionContainerView::SuggestionContainerView(
AssistantController* assistant_controller) AssistantController* assistant_controller)
: assistant_controller_(assistant_controller), : assistant_controller_(assistant_controller),
contents_view_(new views::View()) { contents_view_(new views::View()),
download_request_weak_factory_(this) {
InitLayout(); InitLayout();
// The Assistant controller indirectly owns the view hierarchy to which // The Assistant controller indirectly owns the view hierarchy to which
...@@ -87,23 +85,38 @@ void SuggestionContainerView::InitLayout() { ...@@ -87,23 +85,38 @@ void SuggestionContainerView::InitLayout() {
void SuggestionContainerView::OnSuggestionsAdded( void SuggestionContainerView::OnSuggestionsAdded(
const std::map<int, AssistantSuggestion*>& suggestions) { const std::map<int, AssistantSuggestion*>& suggestions) {
for (const std::pair<int, AssistantSuggestion*>& suggestion : suggestions) { for (const std::pair<int, AssistantSuggestion*>& suggestion : suggestions) {
// We will use the same identifier by which the Assistant interaction model
// uniquely identifies a suggestion to uniquely identify its corresponding
// suggestion chip view.
const int id = suggestion.first;
app_list::SuggestionChipView::Params params; app_list::SuggestionChipView::Params params;
params.text = base::UTF8ToUTF16(suggestion.second->text); params.text = base::UTF8ToUTF16(suggestion.second->text);
// TODO(dmblack): Here we are using a placeholder image for the suggestion if (!suggestion.second->icon_url.is_empty()) {
// chip icon but we need to handle the actual icon URL. // Initiate a request to download the image for the suggestion chip icon.
if (!suggestion.second->icon_url.is_empty()) // Note that the request is identified by the suggestion id.
params.icon = gfx::CreateVectorIcon( assistant_controller_->DownloadImage(
kCircleIcon, app_list::SuggestionChipView::kIconSizeDip, suggestion.second->icon_url,
gfx::kGoogleGrey300); base::BindOnce(
&SuggestionContainerView::OnSuggestionChipIconDownloaded,
views::View* suggestion_chip_view = download_request_weak_factory_.GetWeakPtr(), id));
// To reserve layout space until the actual icon can be downloaded, we
// supply an empty placeholder image to the suggestion chip view.
params.icon = gfx::ImageSkia();
}
app_list::SuggestionChipView* suggestion_chip_view =
new app_list::SuggestionChipView(params, /*listener=*/this); new app_list::SuggestionChipView(params, /*listener=*/this);
// When adding a SuggestionChipView, we give the view the same id by which // Given a suggestion chip view, we need to be able to look up the id of
// the interaction model identifies the corresponding suggestion. This // the underlying suggestion. This is used for handling press events.
// allows us to look up the suggestion for the view during event handling. suggestion_chip_view->set_id(id);
suggestion_chip_view->set_id(suggestion.first);
// Given an id, we also want to be able to look up the corresponding
// suggestion chip view. This is used for handling icon download events.
suggestion_chip_views_[id] = suggestion_chip_view;
contents_view_->AddChildView(suggestion_chip_view); contents_view_->AddChildView(suggestion_chip_view);
} }
...@@ -112,11 +125,25 @@ void SuggestionContainerView::OnSuggestionsAdded( ...@@ -112,11 +125,25 @@ void SuggestionContainerView::OnSuggestionsAdded(
} }
void SuggestionContainerView::OnSuggestionsCleared() { void SuggestionContainerView::OnSuggestionsCleared() {
// Abort any download requests in progress.
download_request_weak_factory_.InvalidateWeakPtrs();
SetVisible(false); SetVisible(false);
// When modifying the view hierarchy, make sure we keep our view cache synced.
contents_view_->RemoveAllChildViews(/*delete_children=*/true); contents_view_->RemoveAllChildViews(/*delete_children=*/true);
suggestion_chip_views_.clear();
UpdateContentsBounds(); UpdateContentsBounds();
} }
void SuggestionContainerView::OnSuggestionChipIconDownloaded(
int id,
const gfx::ImageSkia& icon) {
if (!icon.isNull())
suggestion_chip_views_[id]->SetIcon(icon);
}
void SuggestionContainerView::OnSuggestionChipPressed( void SuggestionContainerView::OnSuggestionChipPressed(
app_list::SuggestionChipView* suggestion_chip_view) { app_list::SuggestionChipView* suggestion_chip_view) {
assistant_controller_->OnSuggestionChipPressed(suggestion_chip_view->id()); assistant_controller_->OnSuggestionChipPressed(suggestion_chip_view->id());
......
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
#ifndef ASH_ASSISTANT_UI_SUGGESTION_CONTAINER_VIEW_H_ #ifndef ASH_ASSISTANT_UI_SUGGESTION_CONTAINER_VIEW_H_
#define ASH_ASSISTANT_UI_SUGGESTION_CONTAINER_VIEW_H_ #define ASH_ASSISTANT_UI_SUGGESTION_CONTAINER_VIEW_H_
#include <map>
#include "ash/assistant/model/assistant_interaction_model_observer.h" #include "ash/assistant/model/assistant_interaction_model_observer.h"
#include "base/macros.h" #include "base/macros.h"
#include "ui/app_list/views/suggestion_chip_view.h" #include "ui/app_list/views/suggestion_chip_view.h"
...@@ -40,9 +42,20 @@ class SuggestionContainerView : public views::ScrollView, ...@@ -40,9 +42,20 @@ class SuggestionContainerView : public views::ScrollView,
void InitLayout(); void InitLayout();
void UpdateContentsBounds(); void UpdateContentsBounds();
// Invoked on suggestion chip icon downloaded event.
void OnSuggestionChipIconDownloaded(int id, const gfx::ImageSkia& icon);
AssistantController* const assistant_controller_; // Owned by Shell. AssistantController* const assistant_controller_; // Owned by Shell.
views::View* contents_view_; // Owned by view hierarchy. views::View* contents_view_; // 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.
std::map<int, app_list::SuggestionChipView*> suggestion_chip_views_;
// Weak pointer factory used for image downloading requests.
base::WeakPtrFactory<SuggestionContainerView> download_request_weak_factory_;
DISALLOW_COPY_AND_ASSIGN(SuggestionContainerView); DISALLOW_COPY_AND_ASSIGN(SuggestionContainerView);
}; };
......
...@@ -20,6 +20,7 @@ mojom("interfaces_internal") { ...@@ -20,6 +20,7 @@ mojom("interfaces_internal") {
"ash_message_center_controller.mojom", "ash_message_center_controller.mojom",
"assistant_card_renderer.mojom", "assistant_card_renderer.mojom",
"assistant_controller.mojom", "assistant_controller.mojom",
"assistant_image_downloader.mojom",
"cast_config.mojom", "cast_config.mojom",
"constants.mojom", "constants.mojom",
"cros_display_config.mojom", "cros_display_config.mojom",
......
...@@ -5,12 +5,12 @@ ...@@ -5,12 +5,12 @@
module ash.mojom; module ash.mojom;
import "ash/public/interfaces/assistant_card_renderer.mojom"; import "ash/public/interfaces/assistant_card_renderer.mojom";
import "ash/public/interfaces/assistant_image_downloader.mojom";
import "chromeos/services/assistant/public/mojom/assistant.mojom"; import "chromeos/services/assistant/public/mojom/assistant.mojom";
import "ui/gfx/geometry/mojo/geometry.mojom"; import "ui/gfx/geometry/mojo/geometry.mojom";
import "url/mojom/url.mojom"; import "url/mojom/url.mojom";
// Interface for AssistantManagerService to communicate with // Interface to AssistantController which is owned by Shell in Ash.
// AssistantController.
interface AssistantController { interface AssistantController {
// Provides a reference to the underlying |assistant| service. // Provides a reference to the underlying |assistant| service.
SetAssistant(chromeos.assistant.mojom.Assistant assistant); SetAssistant(chromeos.assistant.mojom.Assistant assistant);
...@@ -19,6 +19,11 @@ interface AssistantController { ...@@ -19,6 +19,11 @@ interface AssistantController {
// AssistantClient. // AssistantClient.
SetAssistantCardRenderer(AssistantCardRenderer assistant_card_renderer); SetAssistantCardRenderer(AssistantCardRenderer assistant_card_renderer);
// Provides an interface to the |assistant_image_downloader| owned by
// AssistantClient.
SetAssistantImageDownloader(
AssistantImageDownloader assistant_image_downloader);
// Requests screenshot of specified |rect| region and returns the screenshot // Requests screenshot of specified |rect| region and returns the screenshot
// encoded in JPEG format. If |rect| is empty, it returns fullscreen // encoded in JPEG format. If |rect| is empty, it returns fullscreen
// screenshot. // screenshot.
......
// 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.
module ash.mojom;
import "components/account_id/interfaces/account_id.mojom";
import "ui/gfx/image/mojo/image.mojom";
import "url/mojom/url.mojom";
// Interface for a class which is responsible for downloading images on behalf
// of the Assistant UI in ash.
interface AssistantImageDownloader {
// Downloads the image found at |url| for the profile associated with
// |account_id|. On completion, the supplied callback is run with the
// downloaded |image|. In the event that the download attempt fails, a NULL
// image will be returned.
Download(signin.mojom.AccountId account_id, url.mojom.Url url)
=> (gfx.mojom.ImageSkia image);
};
...@@ -12,7 +12,6 @@ aggregate_vector_icons("ash_vector_icons") { ...@@ -12,7 +12,6 @@ aggregate_vector_icons("ash_vector_icons") {
"assistant.icon", "assistant.icon",
"captive_portal.icon", "captive_portal.icon",
"check_circle.icon", "check_circle.icon",
"circle.icon",
"dictation_off.icon", "dictation_off.icon",
"dictation_on.icon", "dictation_on.icon",
"ime_menu_emoticon.icon", "ime_menu_emoticon.icon",
......
// 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.
CANVAS_DIMENSIONS, 24,
CIRCLE, 12, 12, 12
...@@ -299,6 +299,18 @@ void ProfileHelper::ClearSigninProfile(const base::Closure& on_clear_callback) { ...@@ -299,6 +299,18 @@ void ProfileHelper::ClearSigninProfile(const base::Closure& on_clear_callback) {
->CloseCurrentSigninSession(on_clear_profile_stage_finished_); ->CloseCurrentSigninSession(on_clear_profile_stage_finished_);
} }
Profile* ProfileHelper::GetProfileByAccountId(const AccountId& account_id) {
const user_manager::User* user =
user_manager::UserManager::Get()->FindUser(account_id);
if (!user) {
LOG(WARNING) << "Unable to retrieve user for account_id.";
return nullptr;
}
return GetProfileByUser(user);
}
Profile* ProfileHelper::GetProfileByUser(const user_manager::User* user) { Profile* ProfileHelper::GetProfileByUser(const user_manager::User* user) {
// This map is non-empty only in tests. // This map is non-empty only in tests.
if (!user_to_profile_for_testing_.empty()) { if (!user_to_profile_for_testing_.empty()) {
......
...@@ -148,6 +148,10 @@ class ProfileHelper ...@@ -148,6 +148,10 @@ class ProfileHelper
// Callback can be empty. Not thread-safe. // Callback can be empty. Not thread-safe.
void ClearSigninProfile(const base::Closure& on_clear_callback); void ClearSigninProfile(const base::Closure& on_clear_callback);
// Returns profile of the user associated with |account_id| if it is created
// and fully initialized. Otherwise, returns NULL.
Profile* GetProfileByAccountId(const AccountId& account_id);
// Returns profile of the |user| if it is created and fully initialized. // Returns profile of the |user| if it is created and fully initialized.
// Otherwise, returns NULL. // Otherwise, returns NULL.
Profile* GetProfileByUser(const user_manager::User* user); Profile* GetProfileByUser(const user_manager::User* user);
......
...@@ -3715,6 +3715,8 @@ split_static_library("ui") { ...@@ -3715,6 +3715,8 @@ split_static_library("ui") {
"ash/assistant/assistant_context.h", "ash/assistant/assistant_context.h",
"ash/assistant/assistant_context_util.cc", "ash/assistant/assistant_context_util.cc",
"ash/assistant/assistant_context_util.h", "ash/assistant/assistant_context_util.h",
"ash/assistant/assistant_image_downloader.cc",
"ash/assistant/assistant_image_downloader.h",
"ash/assistant/platform_audio_input_host.cc", "ash/assistant/platform_audio_input_host.cc",
"ash/assistant/platform_audio_input_host.h", "ash/assistant/platform_audio_input_host.h",
] ]
......
...@@ -11,7 +11,6 @@ ...@@ -11,7 +11,6 @@
#include "ash/public/interfaces/constants.mojom.h" #include "ash/public/interfaces/constants.mojom.h"
#include "base/optional.h" #include "base/optional.h"
#include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chrome/browser/chromeos/profiles/profile_helper.h"
#include "components/user_manager/user_manager.h"
#include "content/public/browser/browser_context.h" #include "content/public/browser/browser_context.h"
#include "content/public/browser/render_view_host.h" #include "content/public/browser/render_view_host.h"
#include "content/public/browser/render_widget_host_view.h" #include "content/public/browser/render_widget_host_view.h"
...@@ -37,18 +36,11 @@ class AssistantCard : public content::WebContentsDelegate, ...@@ -37,18 +36,11 @@ class AssistantCard : public content::WebContentsDelegate,
ash::mojom::AssistantCardParamsPtr params, ash::mojom::AssistantCardParamsPtr params,
ash::mojom::AssistantCardRenderer::RenderCallback callback) ash::mojom::AssistantCardRenderer::RenderCallback callback)
: assistant_card_renderer_(assistant_card_renderer) { : assistant_card_renderer_(assistant_card_renderer) {
const user_manager::User* user = Profile* profile =
user_manager::UserManager::Get()->FindUser(account_id); chromeos::ProfileHelper::Get()->GetProfileByAccountId(account_id);
if (!user) {
LOG(WARNING) << "Unable to retrieve user for account_id.";
return;
}
Profile* profile = chromeos::ProfileHelper::Get()->GetProfileByUser(user);
if (!profile) { if (!profile) {
LOG(WARNING) << "Unable to retrieve profile for user."; LOG(WARNING) << "Unable to retrieve profile for account_id.";
return; return;
} }
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "ash/public/interfaces/voice_interaction_controller.mojom.h" #include "ash/public/interfaces/voice_interaction_controller.mojom.h"
#include "chrome/browser/chromeos/arc/voice_interaction/voice_interaction_controller_client.h" #include "chrome/browser/chromeos/arc/voice_interaction/voice_interaction_controller_client.h"
#include "chrome/browser/ui/ash/assistant/assistant_card_renderer.h" #include "chrome/browser/ui/ash/assistant/assistant_card_renderer.h"
#include "chrome/browser/ui/ash/assistant/assistant_image_downloader.h"
#include "chromeos/services/assistant/public/mojom/constants.mojom.h" #include "chromeos/services/assistant/public/mojom/constants.mojom.h"
#include "services/service_manager/public/cpp/connector.h" #include "services/service_manager/public/cpp/connector.h"
...@@ -40,6 +41,7 @@ AssistantClient::~AssistantClient() { ...@@ -40,6 +41,7 @@ AssistantClient::~AssistantClient() {
void AssistantClient::MaybeInit(service_manager::Connector* connector) { void AssistantClient::MaybeInit(service_manager::Connector* connector) {
if (initialized_) if (initialized_)
return; return;
initialized_ = true; initialized_ = true;
connector->BindInterface(chromeos::assistant::mojom::kServiceName, connector->BindInterface(chromeos::assistant::mojom::kServiceName,
&assistant_connection_); &assistant_connection_);
...@@ -55,7 +57,9 @@ void AssistantClient::MaybeInit(service_manager::Connector* connector) { ...@@ -55,7 +57,9 @@ void AssistantClient::MaybeInit(service_manager::Connector* connector) {
assistant_connection_->Init(std::move(client_ptr), std::move(context_ptr), assistant_connection_->Init(std::move(client_ptr), std::move(context_ptr),
std::move(audio_input_ptr)); std::move(audio_input_ptr));
assistant_card_renderer_.reset(new AssistantCardRenderer(connector)); assistant_card_renderer_ = std::make_unique<AssistantCardRenderer>(connector);
assistant_image_downloader_ =
std::make_unique<AssistantImageDownloader>(connector);
} }
void AssistantClient::OnAssistantStatusChanged(bool running) { void AssistantClient::OnAssistantStatusChanged(bool running) {
......
...@@ -18,6 +18,7 @@ class Connector; ...@@ -18,6 +18,7 @@ class Connector;
} // namespace service_manager } // namespace service_manager
class AssistantCardRenderer; class AssistantCardRenderer;
class AssistantImageDownloader;
// Class to handle all assistant in-browser-process functionalities. // Class to handle all assistant in-browser-process functionalities.
class AssistantClient : chromeos::assistant::mojom::Client { class AssistantClient : chromeos::assistant::mojom::Client {
...@@ -45,6 +46,7 @@ class AssistantClient : chromeos::assistant::mojom::Client { ...@@ -45,6 +46,7 @@ class AssistantClient : chromeos::assistant::mojom::Client {
AssistantContext context_; AssistantContext context_;
std::unique_ptr<AssistantCardRenderer> assistant_card_renderer_; std::unique_ptr<AssistantCardRenderer> assistant_card_renderer_;
std::unique_ptr<AssistantImageDownloader> assistant_image_downloader_;
bool initialized_ = false; bool initialized_ = false;
......
// 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 "chrome/browser/ui/ash/assistant/assistant_image_downloader.h"
#include "ash/public/interfaces/assistant_controller.mojom.h"
#include "ash/public/interfaces/constants.mojom.h"
#include "chrome/browser/bitmap_fetcher/bitmap_fetcher.h"
#include "chrome/browser/bitmap_fetcher/bitmap_fetcher_delegate.h"
#include "chrome/browser/chromeos/profiles/profile_helper.h"
#include "content/public/browser/storage_partition.h"
#include "net/base/load_flags.h"
#include "services/service_manager/public/cpp/connector.h"
namespace {
constexpr net::NetworkTrafficAnnotationTag kNetworkTrafficAnnotationTag =
net::DefineNetworkTrafficAnnotation("assistant_image_downloader", R"(
"semantics: {
sender: "Google Assistant"
description:
"The Google Assistant requires dynamic loading of images to "
"provide a media rich user experience. Images are downloaded on "
"an as needed basis."
trigger:
"Generally triggered in direct response to a user issued query. "
"A single query may necessitate the downloading of multiple "
"images."
destination: GOOGLE_OWNED_SERVICE
}
"policy": {
cookies_allowed: NO
setting:
"The Google Assistant can be enabled/disabled in Chrome Settings "
"and is subject to eligibility requirements."
})");
// DownloadTask ----------------------------------------------------------------
class DownloadTask : public BitmapFetcherDelegate {
public:
DownloadTask(Profile* profile,
const GURL& url,
ash::mojom::AssistantImageDownloader::DownloadCallback callback)
: callback_(std::move(callback)) {
StartTask(profile, url);
}
~DownloadTask() override = default;
// BitmapFetcherDelegate:
void OnFetchComplete(const GURL& url, const SkBitmap* bitmap) override {
std::move(callback_).Run(bitmap
? gfx::ImageSkia::CreateFrom1xBitmap(*bitmap)
: gfx::ImageSkia());
delete this;
}
private:
void StartTask(Profile* profile, const GURL& url) {
bitmap_fetcher_ = std::make_unique<BitmapFetcher>(
url, this, kNetworkTrafficAnnotationTag);
bitmap_fetcher_->Init(
/*referrer=*/std::string(), net::URLRequest::NEVER_CLEAR_REFERRER,
net::LOAD_DO_NOT_SEND_COOKIES | net::LOAD_DO_NOT_SAVE_COOKIES |
net::LOAD_DO_NOT_SEND_AUTH_DATA | net::LOAD_MAYBE_USER_GESTURE);
bitmap_fetcher_->Start(
content::BrowserContext::GetDefaultStoragePartition(profile)
->GetURLLoaderFactoryForBrowserProcess()
.get());
}
ash::mojom::AssistantImageDownloader::DownloadCallback callback_;
std::unique_ptr<BitmapFetcher> bitmap_fetcher_;
DISALLOW_COPY_AND_ASSIGN(DownloadTask);
};
} // namespace
// AssistantImageDownloader ----------------------------------------------------
AssistantImageDownloader::AssistantImageDownloader(
service_manager::Connector* connector)
: binding_(this) {
// Bind to the Assistant controller in ash.
ash::mojom::AssistantControllerPtr assistant_controller;
connector->BindInterface(ash::mojom::kServiceName, &assistant_controller);
ash::mojom::AssistantImageDownloaderPtr ptr;
binding_.Bind(mojo::MakeRequest(&ptr));
assistant_controller->SetAssistantImageDownloader(std::move(ptr));
}
AssistantImageDownloader::~AssistantImageDownloader() = default;
void AssistantImageDownloader::Download(
const AccountId& account_id,
const GURL& url,
ash::mojom::AssistantImageDownloader::DownloadCallback callback) {
Profile* profile =
chromeos::ProfileHelper::Get()->GetProfileByAccountId(account_id);
if (!profile) {
LOG(WARNING) << "Unable to retrieve profile for account_id.";
std::move(callback).Run(gfx::ImageSkia());
return;
}
// The download task will delete itself upon task completion.
new DownloadTask(profile, url, std::move(callback));
}
// 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.
#ifndef CHROME_BROWSER_UI_ASH_ASSISTANT_ASSISTANT_IMAGE_DOWNLOADER_H_
#define CHROME_BROWSER_UI_ASH_ASSISTANT_ASSISTANT_IMAGE_DOWNLOADER_H_
#include "ash/public/interfaces/assistant_image_downloader.mojom.h"
#include "base/macros.h"
#include "mojo/public/cpp/bindings/binding.h"
class AccountId;
namespace service_manager {
class Connector;
} // namespace service_manager
// AssistantImageDownloader is the class responsible for downloading images on
// behalf of Assistant UI in ash.
class AssistantImageDownloader : public ash::mojom::AssistantImageDownloader {
public:
explicit AssistantImageDownloader(service_manager::Connector* connector);
~AssistantImageDownloader() override;
// ash::mojom::AssistantImageDownloader:
void Download(
const AccountId& account_id,
const GURL& url,
ash::mojom::AssistantImageDownloader::DownloadCallback callback) override;
private:
mojo::Binding<ash::mojom::AssistantImageDownloader> binding_;
DISALLOW_COPY_AND_ASSIGN(AssistantImageDownloader);
};
#endif // CHROME_BROWSER_UI_ASH_ASSISTANT_ASSISTANT_IMAGE_DOWNLOADER_H_
...@@ -54,16 +54,26 @@ int SuggestionChipView::GetHeightForWidth(int width) const { ...@@ -54,16 +54,26 @@ int SuggestionChipView::GetHeightForWidth(int width) const {
return kPreferredHeightDip; return kPreferredHeightDip;
} }
void SuggestionChipView::ChildVisibilityChanged(views::View* child) {
// When icon visibility is modified we need to update layout padding.
if (child == icon_view_) {
const int padding_left_dip =
icon_view_->visible() ? kIconMarginDip : kPaddingDip;
layout_manager_->set_inside_border_insets(
gfx::Insets(0, padding_left_dip, 0, kPaddingDip));
}
PreferredSizeChanged();
}
void SuggestionChipView::InitLayout(const Params& params) { void SuggestionChipView::InitLayout(const Params& params) {
// Layout padding differs depending on icon visibility. // Layout padding differs depending on icon visibility.
const int padding_left_dip = params.icon ? kIconMarginDip : kPaddingDip; const int padding_left_dip = params.icon ? kIconMarginDip : kPaddingDip;
views::BoxLayout* layout_manager = layout_manager_ = SetLayoutManager(std::make_unique<views::BoxLayout>(
SetLayoutManager(std::make_unique<views::BoxLayout>( views::BoxLayout::Orientation::kHorizontal,
views::BoxLayout::Orientation::kHorizontal, gfx::Insets(0, padding_left_dip, 0, kPaddingDip), kIconMarginDip));
gfx::Insets(0, padding_left_dip, 0, kPaddingDip), kIconMarginDip));
layout_manager->set_cross_axis_alignment( layout_manager_->set_cross_axis_alignment(
views::BoxLayout::CrossAxisAlignment::CROSS_AXIS_ALIGNMENT_CENTER); views::BoxLayout::CrossAxisAlignment::CROSS_AXIS_ALIGNMENT_CENTER);
// Icon. // Icon.
...@@ -119,6 +129,11 @@ bool SuggestionChipView::OnMousePressed(const ui::MouseEvent& event) { ...@@ -119,6 +129,11 @@ bool SuggestionChipView::OnMousePressed(const ui::MouseEvent& event) {
return true; return true;
} }
void SuggestionChipView::SetIcon(const gfx::ImageSkia& icon) {
icon_view_->SetImage(icon);
icon_view_->SetVisible(true);
}
const base::string16& SuggestionChipView::GetText() const { const base::string16& SuggestionChipView::GetText() const {
return text_view_->text(); return text_view_->text();
} }
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "ui/views/view.h" #include "ui/views/view.h"
namespace views { namespace views {
class BoxLayout;
class ImageView; class ImageView;
class Label; class Label;
} // namespace views } // namespace views
...@@ -32,7 +33,7 @@ class APP_LIST_EXPORT SuggestionChipListener { ...@@ -32,7 +33,7 @@ class APP_LIST_EXPORT SuggestionChipListener {
// View representing a suggestion chip. // View representing a suggestion chip.
class APP_LIST_EXPORT SuggestionChipView : public views::View { class APP_LIST_EXPORT SuggestionChipView : public views::View {
public: public:
static constexpr int kIconSizeDip = 20; static constexpr int kIconSizeDip = 16;
// Initialization parameters. // Initialization parameters.
struct Params { struct Params {
...@@ -51,11 +52,14 @@ class APP_LIST_EXPORT SuggestionChipView : public views::View { ...@@ -51,11 +52,14 @@ class APP_LIST_EXPORT SuggestionChipView : public views::View {
// views::View: // views::View:
gfx::Size CalculatePreferredSize() const override; gfx::Size CalculatePreferredSize() const override;
void ChildVisibilityChanged(views::View* child) override;
int GetHeightForWidth(int width) const override; int GetHeightForWidth(int width) const override;
void OnGestureEvent(ui::GestureEvent* event) override; void OnGestureEvent(ui::GestureEvent* event) override;
bool OnMousePressed(const ui::MouseEvent& event) override; bool OnMousePressed(const ui::MouseEvent& event) override;
void OnPaintBackground(gfx::Canvas* canvas) override; void OnPaintBackground(gfx::Canvas* canvas) override;
void SetIcon(const gfx::ImageSkia& icon);
const base::string16& GetText() const; const base::string16& GetText() const;
private: private:
...@@ -65,6 +69,8 @@ class APP_LIST_EXPORT SuggestionChipView : public views::View { ...@@ -65,6 +69,8 @@ class APP_LIST_EXPORT SuggestionChipView : public views::View {
views::Label* text_view_; // Owned by view hierarchy. views::Label* text_view_; // Owned by view hierarchy.
SuggestionChipListener* listener_; SuggestionChipListener* listener_;
views::BoxLayout* layout_manager_; // Owned by view hierarchy.
DISALLOW_COPY_AND_ASSIGN(SuggestionChipView); DISALLOW_COPY_AND_ASSIGN(SuggestionChipView);
}; };
......
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