Commit 557d8e0e authored by Xiyuan Xia's avatar Xiyuan Xia Committed by Commit Bot

mash: Enable answer card

- Add kAnswerCard result type for answer card result;
- Pass answer card preferred size via mojo;
- SearchResultAnswerCardView creates RemoteViewHost only when the
  embedding token changes because the token could be used only once;
- SearchResultWebContents re-creates RemoteViewProvider to ensure
  a valid embedding token in case existing token is invalidated
  when swapping cards but the browser is not aware of that when
  creating a new card;

Bug: 812434
Change-Id: I2a8b61974c46b779d8a61a571e95d8003b2bc123
Reviewed-on: https://chromium-review.googlesource.com/1060280Reviewed-by: default avatarTom Sepez <tsepez@chromium.org>
Reviewed-by: default avatarJames Cook <jamescook@chromium.org>
Commit-Queue: Xiyuan Xia <xiyuan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#559167}
parent cb519573
...@@ -79,6 +79,10 @@ class APP_LIST_MODEL_EXPORT SearchResult { ...@@ -79,6 +79,10 @@ class APP_LIST_MODEL_EXPORT SearchResult {
metadata_->answer_card_contents_token = token; metadata_->answer_card_contents_token = token;
} }
gfx::Size answer_card_size() const {
return metadata_->answer_card_size.value_or(gfx::Size());
}
const std::string& id() const { return metadata_->id; } const std::string& id() const { return metadata_->id; }
double display_score() const { return metadata_->display_score; } double display_score() const { return metadata_->display_score; }
......
...@@ -107,6 +107,8 @@ struct EnumTraits<ash::mojom::SearchResultType, ash::SearchResultType> { ...@@ -107,6 +107,8 @@ struct EnumTraits<ash::mojom::SearchResultType, ash::SearchResultType> {
return ash::mojom::SearchResultType::kOmnibox; return ash::mojom::SearchResultType::kOmnibox;
case ash::SearchResultType::kLauncher: case ash::SearchResultType::kLauncher:
return ash::mojom::SearchResultType::kLauncher; return ash::mojom::SearchResultType::kLauncher;
case ash::SearchResultType::kAnswerCard:
return ash::mojom::SearchResultType::kAnswerCard;
case ash::SearchResultType::kUnknown: case ash::SearchResultType::kUnknown:
break; break;
} }
...@@ -141,6 +143,9 @@ struct EnumTraits<ash::mojom::SearchResultType, ash::SearchResultType> { ...@@ -141,6 +143,9 @@ struct EnumTraits<ash::mojom::SearchResultType, ash::SearchResultType> {
case ash::mojom::SearchResultType::kLauncher: case ash::mojom::SearchResultType::kLauncher:
*out = ash::SearchResultType::kLauncher; *out = ash::SearchResultType::kLauncher;
return true; return true;
case ash::mojom::SearchResultType::kAnswerCard:
*out = ash::SearchResultType::kAnswerCard;
return true;
} }
NOTREACHED(); NOTREACHED();
return false; return false;
......
...@@ -46,6 +46,7 @@ enum class SearchResultType { ...@@ -46,6 +46,7 @@ enum class SearchResultType {
kWebStoreSearch, // A search query in WebStore. kWebStoreSearch, // A search query in WebStore.
kOmnibox, // Results from Omnibox. kOmnibox, // Results from Omnibox.
kLauncher, // Results from launcher search (currently only from Files). kLauncher, // Results from launcher search (currently only from Files).
kAnswerCard, // WebContents based answer card.
// Add new values here. // Add new values here.
}; };
......
...@@ -62,6 +62,12 @@ struct SearchResultMetadata { ...@@ -62,6 +62,12 @@ struct SearchResultMetadata {
// empty before initialized. It's illegal to pass // empty before initialized. It's illegal to pass
// an empty UnguessableToken across processes. So // an empty UnguessableToken across processes. So
// we use a null value when it's empty here. // we use a null value when it's empty here.
gfx.mojom.Size? answer_card_size; // Preferred size of answer card. It is
// unset for non-answer-card results. For
// answer card results, it is set when
// the answer card WebContents finishes
// loading and its renderer notifies it
// about a new contents size.
gfx.mojom.ImageSkia? icon; // The icon of this result. gfx.mojom.ImageSkia? icon; // The icon of this result.
gfx.mojom.ImageSkia? badge_icon; // The badge icon of this result that gfx.mojom.ImageSkia? badge_icon; // The badge icon of this result that
// indicates its type, e.g. installable from // indicates its type, e.g. installable from
...@@ -103,6 +109,7 @@ enum SearchResultType { ...@@ -103,6 +109,7 @@ enum SearchResultType {
kWebStoreSearch, // A search query in WebStore. kWebStoreSearch, // A search query in WebStore.
kOmnibox, // Results from Omninbox. kOmnibox, // Results from Omninbox.
kLauncher, // Results from launcher search (currently only from Files). kLauncher, // Results from launcher search (currently only from Files).
kAnswerCard, // WebContents based answer card.
// Add new values here. // Add new values here.
}; };
......
...@@ -10,13 +10,15 @@ ...@@ -10,13 +10,15 @@
#include "base/observer_list.h" #include "base/observer_list.h"
#include "base/unguessable_token.h" #include "base/unguessable_token.h"
namespace gfx {
class Size;
} // namespace gfx
class GURL; class GURL;
namespace app_list { namespace app_list {
class AnswerCardResult;
}
namespace app_list { class AnswerCardResult;
// Abstract source of contents for AnswerCardSearchProvider. // Abstract source of contents for AnswerCardSearchProvider.
class AnswerCardContents { class AnswerCardContents {
...@@ -49,13 +51,19 @@ class AnswerCardContents { ...@@ -49,13 +51,19 @@ class AnswerCardContents {
// Loads contents from |url|. // Loads contents from |url|.
virtual void LoadURL(const GURL& url) = 0; virtual void LoadURL(const GURL& url) = 0;
// Returns the token associated with the contents. // Returns the token associated with the contents.
virtual const base::UnguessableToken& GetToken() const = 0; virtual const base::UnguessableToken& GetToken() const = 0;
// Returns the preferred contents size.
virtual gfx::Size GetPreferredSize() const = 0;
// Sets the delegate to process contents-related events. // Sets the delegate to process contents-related events.
void SetDelegate(Delegate* delegate); void SetDelegate(Delegate* delegate);
// Registers a result that will be notified of input events for the view. // Registers a result that will be notified of input events for the view.
void RegisterResult(AnswerCardResult* result); void RegisterResult(AnswerCardResult* result);
// Unregisters a result. // Unregisters a result.
void UnregisterResult(AnswerCardResult* result); void UnregisterResult(AnswerCardResult* result);
......
...@@ -22,11 +22,13 @@ AnswerCardResult::AnswerCardResult(Profile* profile, ...@@ -22,11 +22,13 @@ AnswerCardResult::AnswerCardResult(Profile* profile,
contents_(contents) { contents_(contents) {
DCHECK(!stripped_result_url.empty()); DCHECK(!stripped_result_url.empty());
SetDisplayType(ash::SearchResultDisplayType::kCard); SetDisplayType(ash::SearchResultDisplayType::kCard);
SetResultType(ash::SearchResultType::kAnswerCard);
set_id(result_url); set_id(result_url);
set_comparable_id(stripped_result_url); set_comparable_id(stripped_result_url);
set_relevance(1); set_relevance(1);
SetAnswerCardContentsToken(contents ? contents->GetToken() SetAnswerCardContentsToken(contents ? contents->GetToken()
: base::UnguessableToken()); : base::UnguessableToken());
SetAnswerCardSize(contents ? contents->GetPreferredSize() : gfx::Size());
SetTitle(result_title); SetTitle(result_title);
if (contents) if (contents)
......
...@@ -31,6 +31,7 @@ class AnswerCardTestContents : public AnswerCardContents { ...@@ -31,6 +31,7 @@ class AnswerCardTestContents : public AnswerCardContents {
// AnswerCardContents overrides: // AnswerCardContents overrides:
void LoadURL(const GURL& url) override { NOTREACHED(); } void LoadURL(const GURL& url) override { NOTREACHED(); }
const base::UnguessableToken& GetToken() const override { return token_; } const base::UnguessableToken& GetToken() const override { return token_; }
gfx::Size GetPreferredSize() const override { return gfx::Size(); }
private: private:
base::UnguessableToken token_; base::UnguessableToken token_;
......
...@@ -63,6 +63,7 @@ class MockAnswerCardContents : public AnswerCardContents { ...@@ -63,6 +63,7 @@ class MockAnswerCardContents : public AnswerCardContents {
// AnswerCardContents overrides: // AnswerCardContents overrides:
MOCK_METHOD1(LoadURL, void(const GURL& url)); MOCK_METHOD1(LoadURL, void(const GURL& url));
MOCK_CONST_METHOD0(GetToken, const base::UnguessableToken&()); MOCK_CONST_METHOD0(GetToken, const base::UnguessableToken&());
MOCK_CONST_METHOD0(GetPreferredSize, gfx::Size());
private: private:
DISALLOW_COPY_AND_ASSIGN(MockAnswerCardContents); DISALLOW_COPY_AND_ASSIGN(MockAnswerCardContents);
......
...@@ -169,9 +169,6 @@ AnswerCardWebContents::AnswerCardWebContents(Profile* profile) ...@@ -169,9 +169,6 @@ AnswerCardWebContents::AnswerCardWebContents(Profile* profile)
web_view_->SetResizeBackgroundColor(SK_ColorTRANSPARENT); web_view_->SetResizeBackgroundColor(SK_ColorTRANSPARENT);
token_ = AnswerCardContentsRegistry::Get()->Register(web_view_.get()); token_ = AnswerCardContentsRegistry::Get()->Register(web_view_.get());
} else {
remote_view_provider_ = std::make_unique<views::RemoteViewProvider>(
web_contents_->GetNativeView());
} }
} }
...@@ -198,14 +195,18 @@ const base::UnguessableToken& AnswerCardWebContents::GetToken() const { ...@@ -198,14 +195,18 @@ const base::UnguessableToken& AnswerCardWebContents::GetToken() const {
return token_; return token_;
} }
gfx::Size AnswerCardWebContents::GetPreferredSize() const {
return preferred_size_;
}
void AnswerCardWebContents::ResizeDueToAutoResize( void AnswerCardWebContents::ResizeDueToAutoResize(
content::WebContents* web_contents, content::WebContents* web_contents,
const gfx::Size& new_size) { const gfx::Size& new_size) {
delegate()->UpdatePreferredSize(this); if (preferred_size_ == new_size)
if (web_view_) return;
web_view_->SetPreferredSize(new_size);
// TODO(https://crbug.com/812434): Support preferred size change for mash. preferred_size_ = new_size;
delegate()->UpdatePreferredSize(this);
} }
content::WebContents* AnswerCardWebContents::OpenURLFromTab( content::WebContents* AnswerCardWebContents::OpenURLFromTab(
...@@ -265,11 +266,13 @@ void AnswerCardWebContents::DidFinishNavigation( ...@@ -265,11 +266,13 @@ void AnswerCardWebContents::DidFinishNavigation(
} }
void AnswerCardWebContents::DidStopLoading() { void AnswerCardWebContents::DidStopLoading() {
if (!remote_view_provider_) { if (web_view_) {
delegate()->OnContentsReady(this); delegate()->OnContentsReady(this);
return; return;
} }
remote_view_provider_ = std::make_unique<views::RemoteViewProvider>(
web_contents_->GetNativeView());
remote_view_provider_->GetEmbedToken( remote_view_provider_->GetEmbedToken(
base::BindOnce(&AnswerCardWebContents::OnGotEmbedTokenAndNotify, base::BindOnce(&AnswerCardWebContents::OnGotEmbedTokenAndNotify,
weak_ptr_factory_.GetWeakPtr())); weak_ptr_factory_.GetWeakPtr()));
......
...@@ -34,6 +34,7 @@ class AnswerCardWebContents : public AnswerCardContents, ...@@ -34,6 +34,7 @@ class AnswerCardWebContents : public AnswerCardContents,
// AnswerCardContents overrides: // AnswerCardContents overrides:
void LoadURL(const GURL& url) override; void LoadURL(const GURL& url) override;
const base::UnguessableToken& GetToken() const override; const base::UnguessableToken& GetToken() const override;
gfx::Size GetPreferredSize() const override;
// content::WebContentsDelegate overrides: // content::WebContentsDelegate overrides:
void ResizeDueToAutoResize(content::WebContents* web_contents, void ResizeDueToAutoResize(content::WebContents* web_contents,
...@@ -76,6 +77,9 @@ class AnswerCardWebContents : public AnswerCardContents, ...@@ -76,6 +77,9 @@ class AnswerCardWebContents : public AnswerCardContents,
// the native window of |web_contents_|. // the native window of |web_contents_|.
base::UnguessableToken token_; base::UnguessableToken token_;
// Preferred size of web contents.
gfx::Size preferred_size_;
// Helper to prepare the native view of |web_contents_| to be embedded under // Helper to prepare the native view of |web_contents_| to be embedded under
// mash. // mash.
std::unique_ptr<views::RemoteViewProvider> remote_view_provider_; std::unique_ptr<views::RemoteViewProvider> remote_view_provider_;
......
...@@ -109,6 +109,13 @@ void ChromeSearchResult::SetAnswerCardContentsToken( ...@@ -109,6 +109,13 @@ void ChromeSearchResult::SetAnswerCardContentsToken(
updater->SetSearchResultMetadata(id(), CloneMetadata()); updater->SetSearchResultMetadata(id(), CloneMetadata());
} }
void ChromeSearchResult::SetAnswerCardSize(const gfx::Size& size) {
metadata_->answer_card_size = size;
AppListModelUpdater* updater = model_updater();
if (updater)
updater->SetSearchResultMetadata(id(), CloneMetadata());
}
void ChromeSearchResult::SetPercentDownloaded(int percent_downloaded) { void ChromeSearchResult::SetPercentDownloaded(int percent_downloaded) {
AppListModelUpdater* updater = model_updater(); AppListModelUpdater* updater = model_updater();
if (updater) if (updater)
......
...@@ -72,6 +72,7 @@ class ChromeSearchResult { ...@@ -72,6 +72,7 @@ class ChromeSearchResult {
void SetActions(const Actions& actions); void SetActions(const Actions& actions);
void SetIsOmniboxSearch(bool is_omnibox_search); void SetIsOmniboxSearch(bool is_omnibox_search);
void SetAnswerCardContentsToken(const base::UnguessableToken& token); void SetAnswerCardContentsToken(const base::UnguessableToken& token);
void SetAnswerCardSize(const gfx::Size& size);
void SetIsInstalling(bool is_installing); void SetIsInstalling(bool is_installing);
void SetIcon(const gfx::ImageSkia& icon); void SetIcon(const gfx::ImageSkia& icon);
void SetBadgeIcon(const gfx::ImageSkia& badge_icon); void SetBadgeIcon(const gfx::ImageSkia& badge_icon);
......
...@@ -24,7 +24,6 @@ ...@@ -24,7 +24,6 @@
#include "chrome/browser/ui/app_list/search/search_controller.h" #include "chrome/browser/ui/app_list/search/search_controller.h"
#include "chrome/browser/ui/app_list/search/settings_shortcut/settings_shortcut_provider.h" #include "chrome/browser/ui/app_list/search/settings_shortcut/settings_shortcut_provider.h"
#include "chrome/browser/ui/app_list/search/webstore/webstore_provider.h" #include "chrome/browser/ui/app_list/search/webstore/webstore_provider.h"
#include "chrome/browser/ui/ash/ash_util.h"
#include "chrome/common/chrome_switches.h" #include "chrome/common/chrome_switches.h"
#include "components/arc/arc_util.h" #include "components/arc/arc_util.h"
...@@ -90,7 +89,7 @@ std::unique_ptr<SearchController> CreateSearchController( ...@@ -90,7 +89,7 @@ std::unique_ptr<SearchController> CreateSearchController(
webstore_group_id, webstore_group_id,
std::make_unique<WebstoreProvider>(profile, list_controller)); std::make_unique<WebstoreProvider>(profile, list_controller));
} }
if (features::IsAnswerCardEnabled() && !ash_util::IsRunningInMash()) { if (features::IsAnswerCardEnabled()) {
controller->AddProvider( controller->AddProvider(
answer_card_group_id, answer_card_group_id,
std::make_unique<AnswerCardSearchProvider>( std::make_unique<AnswerCardSearchProvider>(
......
...@@ -80,20 +80,24 @@ class SearchResultAnswerCardView::SearchAnswerContainerView ...@@ -80,20 +80,24 @@ class SearchResultAnswerCardView::SearchAnswerContainerView
} }
bool SetSearchResult(SearchResult* search_result) { bool SetSearchResult(SearchResult* search_result) {
views::View* const old_result_view = child_count() ? child_at(0) : nullptr; const base::Optional<base::UnguessableToken> old_token =
views::View* const new_result_view = search_result_ ? search_result_->answer_card_contents_token()
search_result : base::nullopt;
? GetViewByToken(search_result->answer_card_contents_token()) const base::Optional<base::UnguessableToken> new_token =
: nullptr; search_result ? search_result->answer_card_contents_token()
: base::nullopt;
if (old_result_view != new_result_view) {
if (old_result_view != nullptr) views::View* result_view = child_count() ? child_at(0) : nullptr;
RemoveChildView(old_result_view); if (old_token != new_token) {
if (new_result_view != nullptr) RemoveAllChildViews(true /* delete_children */);
AddChildView(new_result_view);
result_view = GetViewByToken(new_token);
if (result_view)
AddChildView(result_view);
} }
base::string16 old_title, new_title; base::string16 old_title;
base::string16 new_title;
if (search_result_) { if (search_result_) {
search_result_->RemoveObserver(this); search_result_->RemoveObserver(this);
old_title = search_result_->title(); old_title = search_result_->title();
...@@ -101,6 +105,9 @@ class SearchResultAnswerCardView::SearchAnswerContainerView ...@@ -101,6 +105,9 @@ class SearchResultAnswerCardView::SearchAnswerContainerView
search_result_ = search_result; search_result_ = search_result;
if (search_result_) { if (search_result_) {
search_result_->AddObserver(this); search_result_->AddObserver(this);
if (result_view)
result_view->SetPreferredSize(search_result_->answer_card_size());
new_title = search_result_->title(); new_title = search_result_->title();
SetAccessibleName(new_title); SetAccessibleName(new_title);
} }
...@@ -153,7 +160,10 @@ class SearchResultAnswerCardView::SearchAnswerContainerView ...@@ -153,7 +160,10 @@ class SearchResultAnswerCardView::SearchAnswerContainerView
} }
// SearchResultObserver overrides: // SearchResultObserver overrides:
void OnResultDestroying() override { search_result_ = nullptr; } void OnResultDestroying() override {
RemoveAllChildViews(true /* delete_children */);
search_result_ = nullptr;
}
private: private:
AppListViewDelegate* const view_delegate_; // Not owned. AppListViewDelegate* const view_delegate_; // Not owned.
......
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