Skip to content

Commit

Permalink
[ScreenAI] Adds an item for Pdf Ocr to the context menu.
Browse files Browse the repository at this point in the history
An item with two submenu items is added to the context menu. This
context menu item is visible to the user when they open the menu on the pdf viewer. A screenshot of this context menu can be found in the
following link: https://screenshot.googleplex.com/9qntRNjXWkEmgkM.png.
Also, when "Always" is selected, it will show a checked item with
text, "Convert image to text", on the context menu as depicted in the
following link: https://screenshot.googleplex.com/6VtUSeRGqx7p7XB.png.

AX-Relnotes: n/a
Bug: 1393069
Change-Id: I227c09478aa9df62f71d0309889b45eda5f1aacc
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4061959
Reviewed-by: Ramin Halavati <rhalavati@chromium.org>
Reviewed-by: Tommy Nyquist <nyquist@chromium.org>
Reviewed-by: Ted Choc <tedchoc@chromium.org>
Commit-Queue: Kyungjun Lee <kyungjunlee@google.com>
Cr-Commit-Position: refs/heads/main@{#1084543}
  • Loading branch information
Kyungjun Lee authored and Chromium LUCI CQ committed Dec 16, 2022
1 parent 9fd281c commit 0dcd7c3
Show file tree
Hide file tree
Showing 21 changed files with 409 additions and 55 deletions.
8 changes: 6 additions & 2 deletions chrome/app/chrome_command_ids.h
Expand Up @@ -331,7 +331,6 @@
#define IDC_CONTENT_CONTEXT_SPELLING_SUGGESTION 50157
#define IDC_CONTENT_CONTEXT_SPELLING_TOGGLE 50158
#define IDC_CONTENT_CONTEXT_OPEN_IN_READ_ANYTHING 50159
#define IDC_CONTENT_CONTEXT_RUN_PDF_OCR 50160
#define IDC_CONTENT_CONTEXT_INSPECTBACKGROUNDPAGE 50161
#define IDC_CONTENT_CONTEXT_RELOAD_PACKAGED_APP 50162
#define IDC_CONTENT_CONTEXT_RESTART_PACKAGED_APP 50163
Expand Down Expand Up @@ -454,7 +453,12 @@
#if BUILDFLAG(ENABLE_SCREEN_AI_SERVICE)
// Screen AI Visual Annotations.
#define IDC_RUN_SCREEN_AI_VISUAL_ANNOTATIONS 52420
#endif
#endif // BUILDFLAG(ENABLE_SCREEN_AI_SERVICE)

// PDF OCR
#define IDC_CONTENT_CONTEXT_PDF_OCR 52421
#define IDC_CONTENT_CONTEXT_PDF_OCR_ALWAYS 52422
#define IDC_CONTENT_CONTEXT_PDF_OCR_ONCE 52423

// Tab Search
#define IDC_TAB_SEARCH 52500
Expand Down
24 changes: 18 additions & 6 deletions chrome/app/generated_resources.grd
Expand Up @@ -577,9 +577,6 @@ are declared in tools/grit/grit_rule.gni.
<message name="IDS_CONTENT_CONTEXT_READ_ANYTHING" desc="Context menu menuitem to open page in Read Anything view">
Open in Reader
</message>
<message name="IDS_CONTENT_CONTEXT_RUN_PDF_OCR" desc="Context menu menuitem that runs a local machine intelligence model to extract the content of the current PDF and pass it to assisstive technologies.">
Recognize P&amp;DF text
</message>
<message name="IDS_CONTENT_CONTEXT_RELOAD" desc="The name of the Reload command in the content area context menu">
&amp;Reload
</message>
Expand Down Expand Up @@ -749,6 +746,15 @@ are declared in tools/grit/grit_rule.gni.
<message name="IDS_CONTENT_CONTEXT_ACCESSIBILITY_LABELS_SEND_ONCE" desc="The context-menu sub-item that asks whether to integrate the accessibility image labeling service of Google to Chrome, for a single use.">
Just once
</message>
<message name="IDS_CONTENT_CONTEXT_PDF_OCR_MENU_OPTION" desc="The context-menu item that asks whether to use the PDF OCR service to convert image to text.">
Convert image to text
</message>
<message name="IDS_CONTENT_CONTEXT_PDF_OCR_MENU_OPTION_ALWAYS" desc="The context-menu sub-item that asks whether to use the PDF OCR service to convert image to text always.">
Always
</message>
<message name="IDS_CONTENT_CONTEXT_PDF_OCR_MENU_OPTION_ONCE" desc="The context-menu sub-item that asks whether to use the PDF OCR service to convert image to text, for a single use.">
Just once
</message>
<message name="IDS_CONTENT_CONTEXT_SPELLING_ASK_GOOGLE" desc="The context-menu item that asks whether to integrate the spelling service of Google to Chrome.">
Use enhanced spell check
</message>
Expand Down Expand Up @@ -829,9 +835,6 @@ are declared in tools/grit/grit_rule.gni.
<message name="IDS_CONTENT_CONTEXT_READ_ANYTHING" desc="Context menu menuitem to open page in Read Anything view">
Open in Reader
</message>
<message name="IDS_CONTENT_CONTEXT_RUN_PDF_OCR" desc="Context menu menuitem that runs a local machine intelligence model to extract the content of the current PDF and pass it to assisstive technologies.">
Recognize P&amp;DF text
</message>
<message name="IDS_CONTENT_CONTEXT_RELOAD" desc="In Title Case: The name of the Reload command in the content area context menu">
&amp;Reload
</message>
Expand Down Expand Up @@ -1012,6 +1015,15 @@ are declared in tools/grit/grit_rule.gni.
<message name="IDS_CONTENT_CONTEXT_ACCESSIBILITY_LABELS_SEND_ONCE" desc="The context-menu sub-item that asks whether to integrate the accessibility image labeling service of Google to Chrome, for a single use.">
Just Once
</message>
<message name="IDS_CONTENT_CONTEXT_PDF_OCR_MENU_OPTION" desc="The context-menu item that asks whether to use the PDF OCR service to convert image to text.">
Convert image to text
</message>
<message name="IDS_CONTENT_CONTEXT_PDF_OCR_MENU_OPTION_ALWAYS" desc="The context-menu sub-item that asks whether to use the PDF OCR service to convert image to text always.">
Always
</message>
<message name="IDS_CONTENT_CONTEXT_PDF_OCR_MENU_OPTION_ONCE" desc="The context-menu sub-item that asks whether to use the PDF OCR service to convert image to text, for a single use.">
Just once
</message>
<message name="IDS_CONTENT_CONTEXT_SPELLING_ASK_GOOGLE" desc="In Title Case: The context-menu item that asks whether to integrate the spelling service of Google to Chrome.">
Use Enhanced Spell Check
</message>
Expand Down
@@ -0,0 +1 @@
de02f6a2f36ad4994dbee7b7775b7dd264249365
@@ -0,0 +1 @@
12a00036bde11df37a6c08ef9d9a4a3f60e5aa7d
@@ -0,0 +1 @@
6101413baa79ef7b1d10990bb533dd704b27003b

This file was deleted.

2 changes: 2 additions & 0 deletions chrome/browser/BUILD.gn
Expand Up @@ -4067,6 +4067,8 @@ static_library("browser") {
"renderer_context_menu/accessibility_labels_menu_observer.h",
"renderer_context_menu/link_to_text_menu_observer.cc",
"renderer_context_menu/link_to_text_menu_observer.h",
"renderer_context_menu/pdf_ocr_menu_observer.cc",
"renderer_context_menu/pdf_ocr_menu_observer.h",
"renderer_context_menu/render_view_context_menu.cc",
"renderer_context_menu/render_view_context_menu.h",
"renderer_context_menu/spelling_bubble_model.cc",
Expand Down
6 changes: 6 additions & 0 deletions chrome/browser/prefs/browser_prefs.cc
Expand Up @@ -1686,6 +1686,12 @@ void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry,
#endif

registry->RegisterTimePref(prefs::kDIPSTimerLastUpdate, base::Time());

#if BUILDFLAG(ENABLE_SCREEN_AI_SERVICE)
registry->RegisterBooleanPref(
prefs::kAccessibilityPdfOcrAlwaysActive, false,
user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
#endif // BUILDFLAG(ENABLE_SCREEN_AI_SERVICE)
}

void RegisterUserProfilePrefs(user_prefs::PrefRegistrySyncable* registry) {
Expand Down
Expand Up @@ -236,6 +236,28 @@ void MockRenderViewContextMenu::AddAccessibilityLabelsServiceItem(
}
}

void MockRenderViewContextMenu::AddPdfOcrMenuItem(bool is_checked) {
if (is_checked) {
AddCheckItem(
IDC_CONTENT_CONTEXT_PDF_OCR,
l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_PDF_OCR_MENU_OPTION));
} else {
ui::SimpleMenuModel pdf_ocr_submenu_model_(this);
pdf_ocr_submenu_model_.AddItem(
IDC_CONTENT_CONTEXT_PDF_OCR_ALWAYS,
l10n_util::GetStringUTF16(
IDS_CONTENT_CONTEXT_PDF_OCR_MENU_OPTION_ALWAYS));
pdf_ocr_submenu_model_.AddItem(
IDC_CONTENT_CONTEXT_PDF_OCR_ONCE,
l10n_util::GetStringUTF16(
IDS_CONTENT_CONTEXT_PDF_OCR_MENU_OPTION_ONCE));
AddSubMenu(
IDC_CONTENT_CONTEXT_PDF_OCR,
l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_PDF_OCR_MENU_OPTION),
&pdf_ocr_submenu_model_);
}
}

content::RenderViewHost* MockRenderViewContextMenu::GetRenderViewHost() const {
return nullptr;
}
Expand Down
Expand Up @@ -79,6 +79,7 @@ class MockRenderViewContextMenu : public ui::SimpleMenuModel::Delegate,
void RemoveSeparatorBeforeMenuItem(int command_id) override;
void AddSpellCheckServiceItem(bool is_checked) override;
void AddAccessibilityLabelsServiceItem(bool is_checked) override;
void AddPdfOcrMenuItem(bool is_checked) override;
content::RenderViewHost* GetRenderViewHost() const override;
content::BrowserContext* GetBrowserContext() const override;
content::WebContents* GetWebContents() const override;
Expand Down
107 changes: 107 additions & 0 deletions chrome/browser/renderer_context_menu/pdf_ocr_menu_observer.cc
@@ -0,0 +1,107 @@
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/renderer_context_menu/pdf_ocr_menu_observer.h"

#include "chrome/app/chrome_command_ids.h"
#include "chrome/browser/accessibility/accessibility_state_utils.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/renderer_context_menu/render_view_context_menu.h"
#include "chrome/common/pref_names.h"
#include "components/prefs/pref_service.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/context_menu_params.h"
#include "ui/accessibility/accessibility_features.h"

using content::BrowserThread;

namespace {

// Whether the PDF OCR menu item should be shown in the menu. It now depends on
// whether a screen reader is running.
bool ShouldShowPdfOcrMenuItem() {
return accessibility_state_utils::IsScreenReaderEnabled() &&
features::IsPdfOcrEnabled();
}

} // namespace

PdfOcrMenuObserver::PdfOcrMenuObserver(RenderViewContextMenuProxy* proxy)
: proxy_(proxy) {}

PdfOcrMenuObserver::~PdfOcrMenuObserver() = default;

void PdfOcrMenuObserver::InitMenu(const content::ContextMenuParams& params) {
Profile* profile = Profile::FromBrowserContext(proxy_->GetBrowserContext());
DCHECK(profile != nullptr);
if (ShouldShowPdfOcrMenuItem()) {
proxy_->AddPdfOcrMenuItem(profile->GetPrefs()->GetBoolean(
prefs::kAccessibilityPdfOcrAlwaysActive));
}
}

bool PdfOcrMenuObserver::IsCommandIdSupported(int command_id) {
return command_id == IDC_CONTENT_CONTEXT_PDF_OCR ||
command_id == IDC_CONTENT_CONTEXT_PDF_OCR_ALWAYS ||
command_id == IDC_CONTENT_CONTEXT_PDF_OCR_ONCE;
}

bool PdfOcrMenuObserver::IsCommandIdChecked(int command_id) {
DCHECK(IsCommandIdSupported(command_id));
Profile* profile = Profile::FromBrowserContext(proxy_->GetBrowserContext());
DCHECK(profile != nullptr);
if (command_id == IDC_CONTENT_CONTEXT_PDF_OCR ||
command_id == IDC_CONTENT_CONTEXT_PDF_OCR_ALWAYS ||
command_id == IDC_CONTENT_CONTEXT_PDF_OCR_ONCE) {
return profile->GetPrefs()->GetBoolean(
prefs::kAccessibilityPdfOcrAlwaysActive);
}
return false;
}

bool PdfOcrMenuObserver::IsCommandIdEnabled(int command_id) {
DCHECK(IsCommandIdSupported(command_id));
if (command_id == IDC_CONTENT_CONTEXT_PDF_OCR ||
command_id == IDC_CONTENT_CONTEXT_PDF_OCR_ALWAYS ||
command_id == IDC_CONTENT_CONTEXT_PDF_OCR_ONCE) {
return ShouldShowPdfOcrMenuItem();
}
return false;
}

void PdfOcrMenuObserver::ExecuteCommand(int command_id) {
DCHECK(IsCommandIdSupported(command_id));
Profile* profile = Profile::FromBrowserContext(proxy_->GetBrowserContext());
DCHECK(profile != nullptr);
bool is_always_active =
profile->GetPrefs()->GetBoolean(prefs::kAccessibilityPdfOcrAlwaysActive);
switch (command_id) {
case IDC_CONTENT_CONTEXT_PDF_OCR:
// If the user has selected to make PDF OCR always active, we directly
// update the profile and change it to the original menu item when the
// user disables this item.
DCHECK(is_always_active);
profile->GetPrefs()->SetBoolean(prefs::kAccessibilityPdfOcrAlwaysActive,
false);
// TODO(crbug.com/1393069): Stop the PDF OCR if running.
NOTIMPLEMENTED() << "Need to stop PDF OCR accordingly";
break;
case IDC_CONTENT_CONTEXT_PDF_OCR_ALWAYS:
// When a user choose "Always" to run the PDF OCR, we save this
// preference and change this item to a check item in the context menu.
if (!is_always_active) {
profile->GetPrefs()->SetBoolean(prefs::kAccessibilityPdfOcrAlwaysActive,
true);
// TODO(crbug.com/1393069): Start the PDF OCR if true is set.
NOTIMPLEMENTED() << "Need to start PDF OCR accordingly";
}
break;
case IDC_CONTENT_CONTEXT_PDF_OCR_ONCE:
// TODO(crbug.com/1393069): Run PDF OCR once to convert image to text.
NOTIMPLEMENTED() << "Need to run PDF OCR once to convert image to text";
break;
default:
NOTREACHED();
}
}
41 changes: 41 additions & 0 deletions chrome/browser/renderer_context_menu/pdf_ocr_menu_observer.h
@@ -0,0 +1,41 @@
// Copyright 2022 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_RENDERER_CONTEXT_MENU_PDF_OCR_MENU_OBSERVER_H_
#define CHROME_BROWSER_RENDERER_CONTEXT_MENU_PDF_OCR_MENU_OBSERVER_H_

#include <stddef.h>
#include <stdint.h>

#include "base/memory/raw_ptr.h"
#include "components/prefs/pref_member.h"
#include "components/renderer_context_menu/render_view_context_menu_observer.h"

class RenderViewContextMenuProxy;

// An observer that listens to events from the RenderViewContextMenu class and
// shows the PDF OCR menu if a screen reader is enabled.
class PdfOcrMenuObserver : public RenderViewContextMenuObserver {
public:
explicit PdfOcrMenuObserver(RenderViewContextMenuProxy* proxy);

PdfOcrMenuObserver(const PdfOcrMenuObserver&) = delete;
PdfOcrMenuObserver& operator=(const PdfOcrMenuObserver&) = delete;

~PdfOcrMenuObserver() override;

// RenderViewContextMenuObserver implementation.
void InitMenu(const content::ContextMenuParams& params) override;
bool IsCommandIdSupported(int command_id) override;
bool IsCommandIdChecked(int command_id) override;
bool IsCommandIdEnabled(int command_id) override;
void ExecuteCommand(int command_id) override;

private:
// The interface to add a context-menu item and update it. This class uses
// this interface to avoid accessing context-menu items directly.
raw_ptr<RenderViewContextMenuProxy> proxy_;
};

#endif // CHROME_BROWSER_RENDERER_CONTEXT_MENU_PDF_OCR_MENU_OBSERVER_H_

0 comments on commit 0dcd7c3

Please sign in to comment.