Avi Drissman | 3a215d1e | 2022-09-07 19:43:09 | [diff] [blame] | 1 | // Copyright 2019 The Chromium Authors |
David Black | 74869ac | 2018-10-12 02:27:35 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
David Black | 3c1f13a | 2019-11-25 19:01:33 | [diff] [blame] | 5 | #include "ash/assistant/model/ui/assistant_card_element.h" |
David Black | 74869ac | 2018-10-12 02:27:35 | [diff] [blame] | 6 | |
Meilin Wang | 653c534 | 2020-02-19 01:16:15 | [diff] [blame] | 7 | #include <utility> |
| 8 | |
David Black | 6848457e | 2018-11-29 02:36:01 | [diff] [blame] | 9 | #include "ash/assistant/ui/assistant_ui_constants.h" |
Yuki Awano | ca62d09 | 2022-05-24 23:12:24 | [diff] [blame] | 10 | #include "ash/assistant/ui/assistant_view_ids.h" |
Yuki Awano | abc9df0 | 2022-08-09 18:05:39 | [diff] [blame] | 11 | #include "ash/public/cpp/ash_web_view.h" |
Yue Li | 1f80ae7 | 2021-10-28 21:17:13 | [diff] [blame] | 12 | #include "ash/public/cpp/ash_web_view_factory.h" |
David Black | 6848457e | 2018-11-29 02:36:01 | [diff] [blame] | 13 | #include "base/base64.h" |
Arthur Sonzogni | 834e018f | 2023-04-22 10:20:02 | [diff] [blame^] | 14 | #include "base/memory/raw_ptr.h" |
David Black | 6848457e | 2018-11-29 02:36:01 | [diff] [blame] | 15 | |
David Black | 74869ac | 2018-10-12 02:27:35 | [diff] [blame] | 16 | namespace ash { |
| 17 | |
David Black | 76b9ad3 | 2020-01-18 02:01:45 | [diff] [blame] | 18 | // AssistantCardElement::Processor --------------------------------------------- |
| 19 | |
Yue Li | 1f80ae7 | 2021-10-28 21:17:13 | [diff] [blame] | 20 | class AssistantCardElement::Processor : public AshWebView::Observer { |
David Black | 76b9ad3 | 2020-01-18 02:01:45 | [diff] [blame] | 21 | public: |
Meilin Wang | 653c534 | 2020-02-19 01:16:15 | [diff] [blame] | 22 | Processor(AssistantCardElement* card_element, ProcessingCallback callback) |
David Black | 76b9ad3 | 2020-01-18 02:01:45 | [diff] [blame] | 23 | : 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 Wang | 653c534 | 2020-02-19 01:16:15 | [diff] [blame] | 33 | std::move(callback_).Run(); |
David Black | 76b9ad3 | 2020-01-18 02:01:45 | [diff] [blame] | 34 | } |
| 35 | |
| 36 | void Process() { |
Wen-Chien Wang | 6ec2223 | 2022-10-13 21:47:45 | [diff] [blame] | 37 | const int width_dip = |
| 38 | card_element_->viewport_width() - 2 * assistant::ui::kHorizontalMargin; |
David Black | 76b9ad3 | 2020-01-18 02:01:45 | [diff] [blame] | 39 | |
Yuki Awano | ca62d09 | 2022-05-24 23:12:24 | [diff] [blame] | 40 | // 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 Li | 1f80ae7 | 2021-10-28 21:17:13 | [diff] [blame] | 43 | AshWebView::InitParams contents_params; |
David Black | 76b9ad3 | 2020-01-18 02:01:45 | [diff] [blame] | 44 | 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 Awano | abc9df0 | 2022-08-09 18:05:39 | [diff] [blame] | 48 | contents_params.fix_zoom_level_to_one = true; |
David Black | 76b9ad3 | 2020-01-18 02:01:45 | [diff] [blame] | 49 | |
Allen Bauer | 8007242 | 2020-05-13 18:40:26 | [diff] [blame] | 50 | // 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 Li | 1f80ae7 | 2021-10-28 21:17:13 | [diff] [blame] | 52 | contents_view_ = AshWebViewFactory::Get()->Create(contents_params); |
Yuki Awano | ca62d09 | 2022-05-24 23:12:24 | [diff] [blame] | 53 | contents_view_->SetID(AssistantViewID::kAshWebView); |
David Black | 76b9ad3 | 2020-01-18 02:01:45 | [diff] [blame] | 54 | |
| 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 Wang | 653c534 | 2020-02-19 01:16:15 | [diff] [blame] | 61 | base::Base64Encode(card_element_->html(), &encoded_html); |
David Black | 76b9ad3 | 2020-01-18 02:01:45 | [diff] [blame] | 62 | |
| 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 Li | 1f80ae7 | 2021-10-28 21:17:13 | [diff] [blame] | 69 | // AshWebView::Observer: |
David Black | 76b9ad3 | 2020-01-18 02:01:45 | [diff] [blame] | 70 | void DidStopLoading() override { |
| 71 | contents_view_->RemoveObserver(this); |
| 72 | |
| 73 | // Pass ownership of |contents_view_| to the card element that was being |
Meilin Wang | 653c534 | 2020-02-19 01:16:15 | [diff] [blame] | 74 | // processed and notify our |callback_| of the completion. |
| 75 | card_element_->set_contents_view(std::move(contents_view_)); |
| 76 | std::move(callback_).Run(); |
David Black | 76b9ad3 | 2020-01-18 02:01:45 | [diff] [blame] | 77 | } |
| 78 | |
Meilin Wang | 653c534 | 2020-02-19 01:16:15 | [diff] [blame] | 79 | // |card_element_| should outlive the Processor. |
Arthur Sonzogni | 834e018f | 2023-04-22 10:20:02 | [diff] [blame^] | 80 | const raw_ptr<AssistantCardElement, ExperimentalAsh> card_element_; |
David Black | 76b9ad3 | 2020-01-18 02:01:45 | [diff] [blame] | 81 | ProcessingCallback callback_; |
| 82 | |
Yue Li | 1f80ae7 | 2021-10-28 21:17:13 | [diff] [blame] | 83 | std::unique_ptr<AshWebView> contents_view_; |
David Black | 76b9ad3 | 2020-01-18 02:01:45 | [diff] [blame] | 84 | }; |
| 85 | |
David Black | 74869ac | 2018-10-12 02:27:35 | [diff] [blame] | 86 | // AssistantCardElement -------------------------------------------------------- |
| 87 | |
Leo Liu | 7ae9eb4 | 2018-10-16 21:31:17 | [diff] [blame] | 88 | AssistantCardElement::AssistantCardElement(const std::string& html, |
Yuki Awano | ca62d09 | 2022-05-24 23:12:24 | [diff] [blame] | 89 | const std::string& fallback, |
| 90 | int viewport_width) |
David Black | 74869ac | 2018-10-12 02:27:35 | [diff] [blame] | 91 | : AssistantUiElement(AssistantUiElementType::kCard), |
| 92 | html_(html), |
Yuki Awano | ca62d09 | 2022-05-24 23:12:24 | [diff] [blame] | 93 | fallback_(fallback), |
| 94 | viewport_width_(viewport_width) {} |
David Black | 74869ac | 2018-10-12 02:27:35 | [diff] [blame] | 95 | |
Meilin Wang | 653c534 | 2020-02-19 01:16:15 | [diff] [blame] | 96 | AssistantCardElement::~AssistantCardElement() { |
| 97 | // |processor_| should be destroyed before |this| has been deleted. |
| 98 | processor_.reset(); |
| 99 | } |
David Black | 74869ac | 2018-10-12 02:27:35 | [diff] [blame] | 100 | |
David Black | e441cd0 | 2020-01-16 22:35:24 | [diff] [blame] | 101 | void AssistantCardElement::Process(ProcessingCallback callback) { |
Meilin Wang | 653c534 | 2020-02-19 01:16:15 | [diff] [blame] | 102 | processor_ = std::make_unique<Processor>(this, std::move(callback)); |
David Black | 6848457e | 2018-11-29 02:36:01 | [diff] [blame] | 103 | processor_->Process(); |
| 104 | } |
| 105 | |
wutao | f996270 | 2022-04-06 23:58:58 | [diff] [blame] | 106 | bool AssistantCardElement::has_contents_view() const { |
| 107 | return !!contents_view_; |
| 108 | } |
| 109 | |
Jeffrey Young | 55181400 | 2020-07-15 01:59:14 | [diff] [blame] | 110 | bool AssistantCardElement::Compare(const AssistantUiElement& other) const { |
| 111 | return other.type() == AssistantUiElementType::kCard && |
| 112 | static_cast<const AssistantCardElement&>(other).html() == html_; |
| 113 | } |
| 114 | |
David Black | 74869ac | 2018-10-12 02:27:35 | [diff] [blame] | 115 | } // namespace ash |