1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
|
// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_ASH_MAHI_WEB_CONTENTS_MAHI_WEB_CONTENTS_MANAGER_IMPL_H_
#define CHROME_BROWSER_ASH_MAHI_WEB_CONTENTS_MAHI_WEB_CONTENTS_MANAGER_IMPL_H_
#include <memory>
#include <string>
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/no_destructor.h"
#include "base/timer/timer.h"
#include "base/unguessable_token.h"
#include "chrome/browser/ash/mahi/web_contents/mahi_content_extraction_delegate.h"
#include "chrome/browser/content_extraction/inner_text.h"
#include "chromeos/components/mahi/public/cpp/mahi_browser_util.h"
#include "chromeos/components/mahi/public/cpp/mahi_util.h"
#include "chromeos/components/mahi/public/cpp/mahi_web_contents_manager.h"
#include "chromeos/crosapi/mojom/mahi.mojom-forward.h"
#include "content/public/browser/scoped_accessibility_mode.h"
#include "content/public/browser/web_contents_observer.h"
#include "ui/accessibility/ax_tree_update.h"
#include "ui/gfx/image/image_skia.h"
#include "url/gurl.h"
namespace content {
class WebContents;
} // namespace content
namespace mahi {
class MockMahiWebContentsManager;
class FakeMahiWebContentsManager;
// MahiPDFObserver is a helper class that observes the accessibility change from
// the PDF. The accessibility updates will then be used to extract the content
// of PDFs.
class MahiPDFObserver : public content::WebContentsObserver {
public:
using PDFContentObservedCallback =
base::OnceCallback<void(const std::vector<ui::AXTreeUpdate>&)>;
MahiPDFObserver(content::WebContents* web_contents,
ui::AXMode accessibility_mode,
ui::AXTreeID tree_id,
PDFContentObservedCallback callback);
MahiPDFObserver(const MahiPDFObserver&) = delete;
MahiPDFObserver& operator=(const MahiPDFObserver&) = delete;
~MahiPDFObserver() override;
// content::WebContentsObserver:
void AccessibilityEventReceived(
const ui::AXUpdatesAndEvents& details) override;
private:
// Timer to stop the observation if it's taking too long.
void OnTimerFired();
base::OneShotTimer timer_;
// ID of the tree that contains the PDF.
const ui::AXTreeID tree_id_;
// Callback to extract the content from update.
PDFContentObservedCallback callback_;
// Store the updates of the tree that contain the PDF.
std::vector<ui::AXTreeUpdate> updates_;
// Enables the accessibility mode for PDF content.
std::unique_ptr<content::ScopedAccessibilityMode> scoped_accessibility_mode_;
base::WeakPtrFactory<MahiPDFObserver> weak_ptr_factory_{this};
};
class MahiWebContentsManagerImpl : public chromeos::MahiWebContentsManager {
public:
MahiWebContentsManagerImpl(const MahiWebContentsManagerImpl&) = delete;
MahiWebContentsManagerImpl& operator=(const MahiWebContentsManagerImpl&) =
delete;
MahiWebContentsManagerImpl();
~MahiWebContentsManagerImpl() override;
// chromeos::MahiWebContentsManager:
void OnFocusedPageLoadComplete(content::WebContents* web_contents) override;
void ClearFocusedWebContentState() override;
void WebContentsDestroyed(content::WebContents* web_contents) override;
void OnContextMenuClicked(int64_t display_id,
chromeos::mahi::ButtonType button_type,
std::u16string_view question,
const gfx::Rect& mahi_menu_bounds) override;
bool IsFocusedPageDistillable() override;
void RequestContent(const base::UnguessableToken& page_id,
chromeos::mahi::GetContentCallback callback) override;
void SetSelectedText(const std::u16string& selected_text) override;
std::u16string GetSelectedText() const override;
private:
// Friends to access some test-only functions.
friend class MockMahiWebContentsManager;
friend class FakeMahiWebContentsManager;
void OnGetInnerText(
const base::UnguessableToken& page_id,
const base::Time& start_time,
std::unique_ptr<content_extraction::InnerTextResult> result);
void OnGetSnapshot(const base::UnguessableToken& page_id,
content::WebContents* web_contents,
const base::Time& start_time,
chromeos::mahi::GetContentCallback callback,
ui::AXTreeUpdate& snapshot);
void OnFinishDistillableCheck(const base::UnguessableToken& page_id,
bool is_distillable);
// Get the page content of normal web pages.
void RequestWebContent(const base::UnguessableToken& page_id,
chromeos::mahi::GetContentCallback callback);
// Get the content of PDFs.
void RequestPDFContent(const base::UnguessableToken& page_id,
chromeos::mahi::GetContentCallback callback);
// Process the AXTreeUpdates received for PDF contents.
void OnGetAXTreeUpdatesForPDF(chromeos::mahi::GetContentCallback callback,
const std::vector<ui::AXTreeUpdate>& updates);
// Gets the favicon from the given web contents. Returns an empty imageskia if
// there is no valid one.
// Virtual so we can override in tests.
virtual gfx::ImageSkia GetFavicon(content::WebContents* web_contents) const;
// Determines if the given web contents should be skipped for distillability
// check.
bool ShouldSkip(content::WebContents* web_contents);
std::unique_ptr<MahiContentExtractionDelegate> content_extraction_delegate_;
// The state of the web content which get focus in the browser.
WebContentState focused_web_content_state_{/*url=*/GURL(), /*title=*/u""};
raw_ptr<content::WebContents> focused_web_contents_;
// Store if the current focused web contents is PDF.
bool is_pdf_focused_web_contents_ = false;
// Observer to observe accessibility changed on PDFs.
std::unique_ptr<MahiPDFObserver> pdf_observer_;
// The user selected text on the current focused web content.
std::u16string selected_text_;
base::WeakPtrFactory<MahiWebContentsManagerImpl> weak_pointer_factory_{this};
};
} // namespace mahi
#endif // CHROME_BROWSER_ASH_MAHI_WEB_CONTENTS_MAHI_WEB_CONTENTS_MANAGER_IMPL_H_
|