blob: 625065c3f43c5dddd91b8c88e5be6bd299935129 [file] [log] [blame]
Avi Drissman3a215d1e2022-09-07 19:43:091// Copyright 2019 The Chromium Authors
David Black74869ac2018-10-12 02:27:352// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
David Black3c1f13a2019-11-25 19:01:335#include "ash/assistant/model/ui/assistant_card_element.h"
David Black74869ac2018-10-12 02:27:356
Meilin Wang653c5342020-02-19 01:16:157#include <utility>
8
David Black6848457e2018-11-29 02:36:019#include "ash/assistant/ui/assistant_ui_constants.h"
Yuki Awanoca62d092022-05-24 23:12:2410#include "ash/assistant/ui/assistant_view_ids.h"
Yuki Awanoabc9df02022-08-09 18:05:3911#include "ash/public/cpp/ash_web_view.h"
Yue Li1f80ae72021-10-28 21:17:1312#include "ash/public/cpp/ash_web_view_factory.h"
David Black6848457e2018-11-29 02:36:0113#include "base/base64.h"
Arthur Sonzogni834e018f2023-04-22 10:20:0214#include "base/memory/raw_ptr.h"
David Black6848457e2018-11-29 02:36:0115
David Black74869ac2018-10-12 02:27:3516namespace ash {
17
David Black76b9ad32020-01-18 02:01:4518// AssistantCardElement::Processor ---------------------------------------------
19
Yue Li1f80ae72021-10-28 21:17:1320class AssistantCardElement::Processor : public AshWebView::Observer {
David Black76b9ad32020-01-18 02:01:4521 public:
Meilin Wang653c5342020-02-19 01:16:1522 Processor(AssistantCardElement* card_element, ProcessingCallback callback)
David Black76b9ad32020-01-18 02:01:4523 : card_element_(card_element), callback_(std::move(callback)) {}
24
25 Processor(const Processor& copy) = delete;
26 Processor& operator=(const Processor& assign) = delete;
27
28 ~Processor() override {
29 if (contents_view_)
30 contents_view_->RemoveObserver(this);
31
32 if (callback_)
Meilin Wang653c5342020-02-19 01:16:1533 std::move(callback_).Run();
David Black76b9ad32020-01-18 02:01:4534 }
35
36 void Process() {
Wen-Chien Wang6ec22232022-10-13 21:47:4537 const int width_dip =
38 card_element_->viewport_width() - 2 * assistant::ui::kHorizontalMargin;
David Black76b9ad32020-01-18 02:01:4539
Yuki Awanoca62d092022-05-24 23:12:2440 // Configure parameters for the card. We want to configure the size as:
41 // - width: It should be width_dip.
42 // - height: It should be calculated from the content.
Yue Li1f80ae72021-10-28 21:17:1343 AshWebView::InitParams contents_params;
David Black76b9ad32020-01-18 02:01:4544 contents_params.enable_auto_resize = true;
45 contents_params.min_size = gfx::Size(width_dip, 1);
46 contents_params.max_size = gfx::Size(width_dip, INT_MAX);
47 contents_params.suppress_navigation = true;
Yuki Awanoabc9df02022-08-09 18:05:3948 contents_params.fix_zoom_level_to_one = true;
David Black76b9ad32020-01-18 02:01:4549
Allen Bauer80072422020-05-13 18:40:2650 // Create |contents_view_| and retain ownership until it is added to the
51 // view hierarchy. If that never happens, it will be still be cleaned up.
Yue Li1f80ae72021-10-28 21:17:1352 contents_view_ = AshWebViewFactory::Get()->Create(contents_params);
Yuki Awanoca62d092022-05-24 23:12:2453 contents_view_->SetID(AssistantViewID::kAshWebView);
David Black76b9ad32020-01-18 02:01:4554
55 // Observe |contents_view_| so that we are notified when loading is
56 // complete.
57 contents_view_->AddObserver(this);
58
59 // Encode the html string to be URL-safe.
60 std::string encoded_html;
Meilin Wang653c5342020-02-19 01:16:1561 base::Base64Encode(card_element_->html(), &encoded_html);
David Black76b9ad32020-01-18 02:01:4562
63 // Navigate to the data URL which represents the card.
64 constexpr char kDataUriPrefix[] = "data:text/html;base64,";
65 contents_view_->Navigate(GURL(kDataUriPrefix + encoded_html));
66 }
67
68 private:
Yue Li1f80ae72021-10-28 21:17:1369 // AshWebView::Observer:
David Black76b9ad32020-01-18 02:01:4570 void DidStopLoading() override {
71 contents_view_->RemoveObserver(this);
72
73 // Pass ownership of |contents_view_| to the card element that was being
Meilin Wang653c5342020-02-19 01:16:1574 // processed and notify our |callback_| of the completion.
75 card_element_->set_contents_view(std::move(contents_view_));
76 std::move(callback_).Run();
David Black76b9ad32020-01-18 02:01:4577 }
78
Meilin Wang653c5342020-02-19 01:16:1579 // |card_element_| should outlive the Processor.
Arthur Sonzogni834e018f2023-04-22 10:20:0280 const raw_ptr<AssistantCardElement, ExperimentalAsh> card_element_;
David Black76b9ad32020-01-18 02:01:4581 ProcessingCallback callback_;
82
Yue Li1f80ae72021-10-28 21:17:1383 std::unique_ptr<AshWebView> contents_view_;
David Black76b9ad32020-01-18 02:01:4584};
85
David Black74869ac2018-10-12 02:27:3586// AssistantCardElement --------------------------------------------------------
87
Leo Liu7ae9eb42018-10-16 21:31:1788AssistantCardElement::AssistantCardElement(const std::string& html,
Yuki Awanoca62d092022-05-24 23:12:2489 const std::string& fallback,
90 int viewport_width)
David Black74869ac2018-10-12 02:27:3591 : AssistantUiElement(AssistantUiElementType::kCard),
92 html_(html),
Yuki Awanoca62d092022-05-24 23:12:2493 fallback_(fallback),
94 viewport_width_(viewport_width) {}
David Black74869ac2018-10-12 02:27:3595
Meilin Wang653c5342020-02-19 01:16:1596AssistantCardElement::~AssistantCardElement() {
97 // |processor_| should be destroyed before |this| has been deleted.
98 processor_.reset();
99}
David Black74869ac2018-10-12 02:27:35100
David Blacke441cd02020-01-16 22:35:24101void AssistantCardElement::Process(ProcessingCallback callback) {
Meilin Wang653c5342020-02-19 01:16:15102 processor_ = std::make_unique<Processor>(this, std::move(callback));
David Black6848457e2018-11-29 02:36:01103 processor_->Process();
104}
105
wutaof9962702022-04-06 23:58:58106bool AssistantCardElement::has_contents_view() const {
107 return !!contents_view_;
108}
109
Jeffrey Young551814002020-07-15 01:59:14110bool AssistantCardElement::Compare(const AssistantUiElement& other) const {
111 return other.type() == AssistantUiElementType::kCard &&
112 static_cast<const AssistantCardElement&>(other).html() == html_;
113}
114
David Black74869ac2018-10-12 02:27:35115} // namespace ash