#include "chrome/renderer/accessibility/read_anything_app_controller.h"
#include <climits>
#include <memory>
#include <queue>
#include <string>
#include <utility>
#include <vector>
#include "base/debug/stack_trace.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/metrics_hashes.h"
#include "base/notreached.h"
#include "base/strings/string_util.h"
#include "base/strings/to_string.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/common/accessibility/read_anything_constants.h"
#include "chrome/renderer/accessibility/ax_tree_distiller.h"
#include "chrome/renderer/accessibility/read_aloud_traversal_utils.h"
#include "chrome/renderer/accessibility/read_anything_node_utils.h"
#include "components/language/core/common/locale_util.h"
#include "components/translate/core/common/translate_constants.h"
#include "content/public/renderer/chrome_object_extensions_utils.h"
#include "content/public/renderer/render_frame.h"
#include "content/public/renderer/render_thread.h"
#include "gin/converter.h"
#include "gin/dictionary.h"
#include "gin/handle.h"
#include "gin/object_template_builder.h"
#include "read_anything_app_controller.h"
#include "services/metrics/public/cpp/mojo_ukm_recorder.h"
#include "services/metrics/public/cpp/ukm_builders.h"
#include "third_party/blink/public/platform/browser_interface_broker_proxy.h"
#include "third_party/blink/public/platform/scheduler/web_agent_group_scheduler.h"
#include "third_party/blink/public/web/web_local_frame.h"
#include "third_party/blink/public/web/web_script_source.h"
#include "third_party/re2/src/re2/re2.h"
#include "third_party/skia/include/core/SkColorSpace.h"
#include "third_party/skia/include/core/SkColorType.h"
#include "third_party/skia/include/core/SkData.h"
#include "third_party/skia/include/core/SkImageInfo.h"
#include "ui/accessibility/accessibility_features.h"
#include "ui/accessibility/ax_enums.mojom-shared.h"
#include "ui/accessibility/ax_node.h"
#include "ui/accessibility/ax_node_id_forward.h"
#include "ui/accessibility/ax_role_properties.h"
#include "ui/accessibility/ax_selection.h"
#include "ui/accessibility/ax_serializable_tree.h"
#include "ui/accessibility/ax_text_utils.h"
#include "ui/accessibility/ax_tree.h"
#include "ui/accessibility/ax_tree_id.h"
#include "ui/accessibility/ax_tree_serializer.h"
#include "ui/accessibility/ax_tree_update.h"
#include "ui/accessibility/mojom/ax_event.mojom.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/gfx/geometry/size.h"
#include "url/url_util.h"
#include "v8/include/v8-context.h"
#include "v8/include/v8-microtask-queue.h"
#include "v8/include/v8-typed-array.h"
namespace {
constexpr char kUndeterminedLocale[] = …;
const double kPostInputDistillSeconds = …;
void SetAXNodeDataChildIds(v8::Isolate* isolate,
gin::Dictionary* v8_dict,
ui::AXNodeData* ax_node_data) { … }
void SetAXNodeDataId(v8::Isolate* isolate,
gin::Dictionary* v8_dict,
ui::AXNodeData* ax_node_data) { … }
void SetAXNodeDataLanguage(v8::Isolate* isolate,
gin::Dictionary* v8_dict,
ui::AXNodeData* ax_node_data) { … }
void SetAXNodeDataName(v8::Isolate* isolate,
gin::Dictionary* v8_dict,
ui::AXNodeData* ax_node_data) { … }
void SetAXNodeDataRole(v8::Isolate* isolate,
gin::Dictionary* v8_dict,
ui::AXNodeData* ax_node_data) { … }
void SetAXNodeDataHtmlTag(v8::Isolate* isolate,
gin::Dictionary* v8_dict,
ui::AXNodeData* ax_node_data) { … }
void SetAXNodeDataDisplay(v8::Isolate* isolate,
gin::Dictionary* v8_dict,
ui::AXNodeData* ax_node_data) { … }
void SetAXNodeDataTextDirection(v8::Isolate* isolate,
gin::Dictionary* v8_dict,
ui::AXNodeData* ax_node_data) { … }
void SetAXNodeDataTextStyle(v8::Isolate* isolate,
gin::Dictionary* v8_dict,
ui::AXNodeData* ax_node_data) { … }
void SetAXNodeDataUrl(v8::Isolate* isolate,
gin::Dictionary* v8_dict,
ui::AXNodeData* ax_node_data) { … }
void SetSelectionAnchorObjectId(v8::Isolate* isolate,
gin::Dictionary* v8_dict,
ui::AXTreeData* ax_tree_data) { … }
void SetSelectionFocusObjectId(v8::Isolate* isolate,
gin::Dictionary* v8_dict,
ui::AXTreeData* ax_tree_data) { … }
void SetSelectionAnchorOffset(v8::Isolate* isolate,
gin::Dictionary* v8_dict,
ui::AXTreeData* ax_tree_data) { … }
void SetSelectionFocusOffset(v8::Isolate* isolate,
gin::Dictionary* v8_dict,
ui::AXTreeData* ax_tree_data) { … }
void SetSelectionIsBackward(v8::Isolate* isolate,
gin::Dictionary* v8_dict,
ui::AXTreeData* ax_tree_data) { … }
void SetAXTreeUpdateRootId(v8::Isolate* isolate,
gin::Dictionary* v8_dict,
ui::AXTreeUpdate* snapshot) { … }
ui::AXTreeUpdate GetSnapshotFromV8SnapshotLite(
v8::Isolate* isolate,
v8::Local<v8::Value> v8_snapshot_lite) { … }
SkBitmap CorrectColorOfBitMap(SkBitmap& originalBitmap) { … }
}
gin::WrapperInfo ReadAnythingAppController::kWrapperInfo = …;
ReadAnythingAppController* ReadAnythingAppController::Install(
content::RenderFrame* render_frame) { … }
ReadAnythingAppController::ReadAnythingAppController(
content::RenderFrame* render_frame)
: … { … }
ReadAnythingAppController::~ReadAnythingAppController() { … }
void ReadAnythingAppController::OnDestruct() { … }
void ReadAnythingAppController::OnNodeDataChanged(
ui::AXTree* tree,
const ui::AXNodeData& old_node_data,
const ui::AXNodeData& new_node_data) { … }
void ReadAnythingAppController::OnNodeWillBeDeleted(ui::AXTree* tree,
ui::AXNode* node) { … }
void ReadAnythingAppController::OnNodeDeleted(ui::AXTree* tree,
ui::AXNodeID node_id) { … }
void ReadAnythingAppController::AccessibilityEventReceived(
const ui::AXTreeID& tree_id,
const std::vector<ui::AXTreeUpdate>& updates,
const std::vector<ui::AXEvent>& events) { … }
void ReadAnythingAppController::ExecuteJavaScript(const std::string& script) { … }
void ReadAnythingAppController::OnActiveAXTreeIDChanged(
const ui::AXTreeID& tree_id,
ukm::SourceId ukm_source_id,
bool is_pdf) { … }
void ReadAnythingAppController::RecordNumSelections() { … }
void ReadAnythingAppController::OnAXTreeDestroyed(const ui::AXTreeID& tree_id) { … }
void ReadAnythingAppController::Distill() { … }
void ReadAnythingAppController::OnAXTreeDistilled(
const ui::AXTreeID& tree_id,
const std::vector<ui::AXNodeID>& content_node_ids) { … }
bool ReadAnythingAppController::PostProcessSelection() { … }
void ReadAnythingAppController::Draw(bool recompute_display_nodes) { … }
void ReadAnythingAppController::DrawSelection() { … }
void ReadAnythingAppController::OnSettingsRestoredFromPrefs(
read_anything::mojom::LineSpacing line_spacing,
read_anything::mojom::LetterSpacing letter_spacing,
const std::string& font,
double font_size,
bool links_enabled,
bool images_enabled,
read_anything::mojom::Colors color,
double speech_rate,
base::Value::Dict voices,
base::Value::List languages_enabled_in_pref,
read_anything::mojom::HighlightGranularity granularity) { … }
void ReadAnythingAppController::ScreenAIServiceReady() { … }
gin::ObjectTemplateBuilder ReadAnythingAppController::GetObjectTemplateBuilder(
v8::Isolate* isolate) { … }
ui::AXNodeID ReadAnythingAppController::RootId() const { … }
ui::AXNodeID ReadAnythingAppController::StartNodeId() const { … }
int ReadAnythingAppController::StartOffset() const { … }
ui::AXNodeID ReadAnythingAppController::EndNodeId() const { … }
int ReadAnythingAppController::EndOffset() const { … }
std::string ReadAnythingAppController::FontName() const { … }
float ReadAnythingAppController::FontSize() const { … }
bool ReadAnythingAppController::LinksEnabled() const { … }
bool ReadAnythingAppController::ImagesEnabled() const { … }
bool ReadAnythingAppController::ImagesFeatureEnabled() const { … }
int ReadAnythingAppController::LetterSpacing() const { … }
int ReadAnythingAppController::LineSpacing() const { … }
int ReadAnythingAppController::ColorTheme() const { … }
double ReadAnythingAppController::SpeechRate() const { … }
std::string ReadAnythingAppController::GetStoredVoice() const { … }
std::vector<std::string> ReadAnythingAppController::GetLanguagesEnabledInPref()
const { … }
int ReadAnythingAppController::HighlightGranularity() const { … }
int ReadAnythingAppController::StandardLineSpacing() const { … }
int ReadAnythingAppController::LooseLineSpacing() const { … }
int ReadAnythingAppController::VeryLooseLineSpacing() const { … }
int ReadAnythingAppController::StandardLetterSpacing() const { … }
int ReadAnythingAppController::WideLetterSpacing() const { … }
int ReadAnythingAppController::VeryWideLetterSpacing() const { … }
int ReadAnythingAppController::DefaultTheme() const { … }
int ReadAnythingAppController::LightTheme() const { … }
int ReadAnythingAppController::DarkTheme() const { … }
int ReadAnythingAppController::YellowTheme() const { … }
int ReadAnythingAppController::BlueTheme() const { … }
bool ReadAnythingAppController::IsHighlightOn() { … }
std::vector<ui::AXNodeID> ReadAnythingAppController::GetChildren(
ui::AXNodeID ax_node_id) const { … }
std::string ReadAnythingAppController::GetDataFontCss(
ui::AXNodeID ax_node_id) const { … }
std::string ReadAnythingAppController::GetHtmlTag(
ui::AXNodeID ax_node_id) const { … }
std::string ReadAnythingAppController::GetLanguage(
ui::AXNodeID ax_node_id) const { … }
std::u16string ReadAnythingAppController::GetTextContent(
ui::AXNodeID ax_node_id) const { … }
std::string ReadAnythingAppController::GetTextDirection(
ui::AXNodeID ax_node_id) const { … }
std::string ReadAnythingAppController::GetUrl(ui::AXNodeID ax_node_id) const { … }
void ReadAnythingAppController::SendGetVoicePackInfoRequest(
const std::string& language) const { … }
void ReadAnythingAppController::OnGetVoicePackInfoResponse(
read_anything::mojom::VoicePackInfoPtr voice_pack_info) { … }
void ReadAnythingAppController::SendInstallVoicePackRequest(
const std::string& language) const { … }
void ReadAnythingAppController::OnInstallVoicePackResponse(
read_anything::mojom::VoicePackInfoPtr voice_pack_info) { … }
std::string ReadAnythingAppController::GetAltText(
ui::AXNodeID ax_node_id) const { … }
bool ReadAnythingAppController::ShouldBold(ui::AXNodeID ax_node_id) const { … }
bool ReadAnythingAppController::IsOverline(ui::AXNodeID ax_node_id) const { … }
bool ReadAnythingAppController::IsLeafNode(ui::AXNodeID ax_node_id) const { … }
bool ReadAnythingAppController::IsReadAloudEnabled() const { … }
bool ReadAnythingAppController::IsChromeOsAsh() const { … }
bool ReadAnythingAppController::IsAutoVoiceSwitchingEnabled() const { … }
bool ReadAnythingAppController::IsLanguagePackDownloadingEnabled() const { … }
bool ReadAnythingAppController::IsAutomaticWordHighlightingEnabled() const { … }
bool ReadAnythingAppController::IsGoogleDocs() const { … }
std::vector<std::string> ReadAnythingAppController::GetSupportedFonts() { … }
std::string ReadAnythingAppController::GetValidatedFontName(
const std::string& font) const { … }
std::vector<std::string> ReadAnythingAppController::GetAllFonts() { … }
void ReadAnythingAppController::RequestImageDataUrl(
ui::AXNodeID node_id) const { … }
void ReadAnythingAppController::OnImageDataDownloaded(
const ui::AXTreeID& tree_id,
ui::AXNodeID node_id,
const SkBitmap& image) { … }
v8::Local<v8::Value> ReadAnythingAppController::GetImageBitmap(
ui::AXNodeID node_id) { … }
std::string ReadAnythingAppController::GetImageDataUrl(
ui::AXNodeID node_id) const { … }
const std::string ReadAnythingAppController::GetDisplayNameForLocale(
const std::string& locale,
const std::string& display_locale) const { … }
const std::string& ReadAnythingAppController::GetLanguageCodeForSpeech() const { … }
bool ReadAnythingAppController::RequiresDistillation() { … }
const std::string& ReadAnythingAppController::GetDefaultLanguageCodeForSpeech()
const { … }
void ReadAnythingAppController::OnConnected() { … }
void ReadAnythingAppController::OnCopy() const { … }
void ReadAnythingAppController::OnFontSizeChanged(bool increase) { … }
void ReadAnythingAppController::OnFontSizeReset() { … }
void ReadAnythingAppController::OnLinksEnabledToggled() { … }
void ReadAnythingAppController::OnImagesEnabledToggled() { … }
void ReadAnythingAppController::OnScroll(bool on_selection) const { … }
void ReadAnythingAppController::OnLinkClicked(ui::AXNodeID ax_node_id) const { … }
void ReadAnythingAppController::OnLetterSpacingChange(int value) { … }
void ReadAnythingAppController::OnLineSpacingChange(int value) { … }
void ReadAnythingAppController::OnThemeChange(int value) { … }
void ReadAnythingAppController::OnFontChange(const std::string& font) { … }
void ReadAnythingAppController::OnSpeechRateChange(double rate) { … }
void ReadAnythingAppController::OnVoiceChange(const std::string& voice,
const std::string& lang) { … }
void ReadAnythingAppController::OnLanguagePrefChange(const std::string& lang,
bool enabled) { … }
void ReadAnythingAppController::TurnedHighlightOn() { … }
void ReadAnythingAppController::TurnedHighlightOff() { … }
double ReadAnythingAppController::GetLineSpacingValue(int line_spacing) const { … }
double ReadAnythingAppController::GetLetterSpacingValue(
int letter_spacing) const { … }
void ReadAnythingAppController::OnSelectionChange(ui::AXNodeID anchor_node_id,
int anchor_offset,
ui::AXNodeID focus_node_id,
int focus_offset) const { … }
void ReadAnythingAppController::OnCollapseSelection() const { … }
void ReadAnythingAppController::ResetGranularityIndex() { … }
void ReadAnythingAppController::InitAXPositionWithNode(
const ui::AXNodeID& starting_node_id) { … }
std::vector<ui::AXNodeID> ReadAnythingAppController::GetCurrentText() { … }
void ReadAnythingAppController::PreprocessTextForSpeech() { … }
void ReadAnythingAppController::MovePositionToNextGranularity() { … }
void ReadAnythingAppController::MovePositionToPreviousGranularity() { … }
int ReadAnythingAppController::GetCurrentTextStartIndex(ui::AXNodeID node_id) { … }
int ReadAnythingAppController::GetCurrentTextEndIndex(ui::AXNodeID node_id) { … }
void ReadAnythingAppController::SetLanguageForTesting(
const std::string& language_code) { … }
void ReadAnythingAppController::SetLanguageCode(const std::string& code) { … }
#if BUILDFLAG(IS_CHROMEOS_ASH)
void ReadAnythingAppController::OnDeviceLocked() {
ExecuteJavaScript("chrome.readingMode.onLockScreen();");
}
#endif
void ReadAnythingAppController::SetDefaultLanguageCode(
const std::string& code) { … }
void ReadAnythingAppController::SetContentForTesting(
v8::Local<v8::Value> v8_snapshot_lite,
std::vector<ui::AXNodeID> content_node_ids) { … }
void ReadAnythingAppController::ShouldShowUI() { … }
void ReadAnythingAppController::OnSpeechPlayingStateChanged(
bool is_speech_active) { … }
int ReadAnythingAppController::GetAccessibleBoundary(const std::u16string& text,
int max_text_length) { … }
v8::Local<v8::Value>
ReadAnythingAppController::GetHighlightForCurrentSegmentIndex(int index) { … }
void ReadAnythingAppController::IncrementMetricCount(
const std::string& metric) { … }
void ReadAnythingAppController::OnScrolledToBottom() { … }
bool ReadAnythingAppController::IsDocsLoadMoreButtonVisible() const { … }