Enable ChromeScreenAI on Windows.
ChromeScreenAI is enabled on Windows. Sandbox is set to allow read only access to installed component folder, this will be removed before launch and replaced with opening required files in the browser and sending their handles to the ScreenAI binary. The component binary path is now stored in InstallState and passed to the service after service is initialized. Bug: 1278249 Change-Id: Ia86e3f6309e55195040ab1927d54ca4f9018ed6f Ax-Relnotes: n/a Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3876149 Reviewed-by: Sorin Jianu <sorin@chromium.org> Reviewed-by: Avi Drissman <avi@chromium.org> Reviewed-by: Alex Gough <ajgo@chromium.org> Reviewed-by: David Tseng <dtseng@chromium.org> Commit-Queue: Ramin Halavati <rhalavati@chromium.org> Reviewed-by: Matthew Denton <mpdenton@chromium.org> Cr-Commit-Position: refs/heads/main@{#1060869}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
c1c47ac43f
commit
fd712d8e30
chrome/browser
components/services/screen_ai
BUILD.gn
buildflags
public
cpp
screen_ai_install_state.ccscreen_ai_install_state.hscreen_ai_install_state_unittest.ccscreen_ai_service_router.ccutilities.ccutilities.h
mojom
sandbox
screen_ai_service_impl.ccscreen_ai_service_impl.hcontent
sandbox/policy/win
@ -55,7 +55,7 @@ void AXScreenAIAnnotator::AnnotateScreenshot(Browser* browser) {
|
||||
|
||||
// TODO(https://crbug.com/1278249): Add UMA for screenshot timing to ensure
|
||||
// the sync method is not blocking the browser process.
|
||||
#if BUILDFLAG(IS_MAC)
|
||||
#if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN)
|
||||
gfx::Image snapshot;
|
||||
if (!ui::GrabViewSnapshot(native_view, gfx::Rect(web_contents->GetSize()),
|
||||
&snapshot)) {
|
||||
|
@ -4262,6 +4262,9 @@ std::wstring ChromeContentBrowserClient::GetAppContainerSidForSandboxType(
|
||||
#endif
|
||||
case sandbox::mojom::Sandbox::kPrintCompositor:
|
||||
case sandbox::mojom::Sandbox::kAudio:
|
||||
#if BUILDFLAG(ENABLE_SCREEN_AI_SERVICE)
|
||||
case sandbox::mojom::Sandbox::kScreenAI:
|
||||
#endif
|
||||
case sandbox::mojom::Sandbox::kSpeechRecognition:
|
||||
case sandbox::mojom::Sandbox::kPdfConversion:
|
||||
case sandbox::mojom::Sandbox::kService:
|
||||
@ -4347,6 +4350,9 @@ bool ChromeContentBrowserClient::PreSpawnChild(
|
||||
case sandbox::mojom::Sandbox::kPrintBackend:
|
||||
#endif
|
||||
case sandbox::mojom::Sandbox::kPrintCompositor:
|
||||
#if BUILDFLAG(ENABLE_SCREEN_AI_SERVICE)
|
||||
case sandbox::mojom::Sandbox::kScreenAI:
|
||||
#endif
|
||||
case sandbox::mojom::Sandbox::kAudio:
|
||||
case sandbox::mojom::Sandbox::kSpeechRecognition:
|
||||
case sandbox::mojom::Sandbox::kPdfConversion:
|
||||
@ -6676,8 +6682,8 @@ bool ChromeContentBrowserClient::SetupEmbedderSandboxParameters(
|
||||
CHECK(client->SetParameter(sandbox::policy::kParamSodaLanguagePackPath,
|
||||
soda_language_pack_path.value()));
|
||||
return true;
|
||||
} else if (sandbox_type == sandbox::mojom::Sandbox::kScreenAI) {
|
||||
#if BUILDFLAG(ENABLE_SCREEN_AI_SERVICE)
|
||||
} else if (sandbox_type == sandbox::mojom::Sandbox::kScreenAI) {
|
||||
// ScreenAI service needs read access to ScreenAI component path, so that it
|
||||
// would be able to find the latest downloaded version, and load its binary
|
||||
// and all enclosed model files.
|
||||
|
@ -70,7 +70,8 @@ void ScreenAIComponentInstallerPolicy::ComponentReady(
|
||||
const base::Version& version,
|
||||
const base::FilePath& install_dir,
|
||||
base::Value manifest) {
|
||||
screen_ai::ScreenAIInstallState::GetInstance()->SetComponentReady();
|
||||
screen_ai::ScreenAIInstallState::GetInstance()->SetComponentReady(
|
||||
install_dir.Append(screen_ai::GetComponentBinaryFileName()));
|
||||
VLOG(1) << "Screen AI Component ready, version " << version.GetString()
|
||||
<< " in " << install_dir.value();
|
||||
}
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "base/bind.h"
|
||||
#include "base/callback.h"
|
||||
#include "base/command_line.h"
|
||||
#include "base/files/file_path.h"
|
||||
#include "base/memory/raw_ptr.h"
|
||||
#include "base/memory/ref_counted.h"
|
||||
#include "base/run_loop.h"
|
||||
@ -2495,8 +2496,10 @@ class PdfOcrContextMenuBrowserTest : public PdfPluginContextMenuBrowserTest,
|
||||
scoped_feature_list_.InitAndDisableFeature(features::kPdfOcr);
|
||||
accessibility_state_utils::OverrideIsScreenReaderEnabledForTesting(
|
||||
IsScreenReaderEnabled());
|
||||
screen_ai::ScreenAIInstallState::GetInstance()->SetComponentReadyForTesting(
|
||||
IsComponentReady());
|
||||
screen_ai::ScreenAIInstallState::GetInstance()
|
||||
->set_component_ready_for_testing(
|
||||
IsComponentReady() ? base::FilePath(FILE_PATH_LITERAL("tmp"))
|
||||
: base::FilePath());
|
||||
}
|
||||
|
||||
PdfOcrContextMenuBrowserTest(const PdfOcrContextMenuBrowserTest&) = delete;
|
||||
|
@ -23,7 +23,7 @@ source_set("screen_ai") {
|
||||
]
|
||||
}
|
||||
|
||||
if (!is_mac) {
|
||||
if (is_linux || is_chromeos) {
|
||||
source_set("screen_ai_sandbox_hook") {
|
||||
sources = [
|
||||
"sandbox/screen_ai_sandbox_hook_linux.cc",
|
||||
@ -73,19 +73,26 @@ source_set("unit_tests") {
|
||||
testonly = true
|
||||
|
||||
sources = [
|
||||
"proto/proto_convertor_unittest.cc",
|
||||
"public/cpp/screen_ai_install_state_unittest.cc",
|
||||
"screen_ai_ax_tree_serializer_unittest.cc",
|
||||
]
|
||||
|
||||
# TODO(https://crbug.com/1278249): Enable after the protobuf issue is fixed.
|
||||
if (!is_win) {
|
||||
sources += [ "proto/proto_convertor_unittest.cc" ]
|
||||
}
|
||||
|
||||
data = [ "//components/test/data/screen_ai/" ]
|
||||
deps = [
|
||||
":screen_ai",
|
||||
":test_support",
|
||||
"//base/test:test_support",
|
||||
"//components/services/screen_ai/proto",
|
||||
"//components/services/screen_ai/public/cpp:screen_ai_install_state",
|
||||
"//testing/gtest",
|
||||
"//ui/accessibility:test_support",
|
||||
]
|
||||
|
||||
if (!is_win) {
|
||||
deps += [ ":test_support" ]
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ import("//build/config/chromecast_build.gni")
|
||||
import("//build/config/chromeos/ui_mode.gni")
|
||||
|
||||
declare_args() {
|
||||
# Screen AI service is still not supported on other platforms.
|
||||
enable_screen_ai_service = is_linux || is_mac || is_chromeos
|
||||
# TODO(https://crbug.com/1278249): Remove this feature flag as now it's
|
||||
# supported on all platforms.
|
||||
enable_screen_ai_service = is_linux || is_mac || is_chromeos || is_win
|
||||
}
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
#include "components/services/screen_ai/public/cpp/screen_ai_install_state.h"
|
||||
|
||||
#include "base/files/file_path.h"
|
||||
#include "base/no_destructor.h"
|
||||
#include "base/ranges/algorithm.h"
|
||||
|
||||
@ -21,7 +22,7 @@ ScreenAIInstallState::~ScreenAIInstallState() = default;
|
||||
void ScreenAIInstallState::AddObserver(
|
||||
ScreenAIInstallState::Observer* observer) {
|
||||
observers_.push_back(observer);
|
||||
if (component_ready_)
|
||||
if (!component_binary_path_.empty())
|
||||
observer->ComponentReady();
|
||||
}
|
||||
|
||||
@ -32,11 +33,16 @@ void ScreenAIInstallState::RemoveObserver(
|
||||
observers_.erase(pos);
|
||||
}
|
||||
|
||||
void ScreenAIInstallState::SetComponentReady() {
|
||||
component_ready_ = true;
|
||||
void ScreenAIInstallState::SetComponentReady(
|
||||
const base::FilePath& component_binary_path) {
|
||||
component_binary_path_ = component_binary_path;
|
||||
|
||||
for (ScreenAIInstallState::Observer* observer : observers_)
|
||||
observer->ComponentReady();
|
||||
}
|
||||
|
||||
bool ScreenAIInstallState::is_component_ready() {
|
||||
return !component_binary_path_.empty();
|
||||
}
|
||||
|
||||
} // namespace screen_ai
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "base/files/file_path.h"
|
||||
#include "base/observer_list_types.h"
|
||||
|
||||
namespace component_updater {
|
||||
@ -34,17 +35,22 @@ class ScreenAIInstallState {
|
||||
void AddObserver(Observer* observer);
|
||||
void RemoveObserver(Observer* observer);
|
||||
|
||||
bool is_component_ready() { return component_ready_; }
|
||||
bool is_component_ready();
|
||||
|
||||
void SetComponentReadyForTesting(bool ready) { component_ready_ = ready; }
|
||||
base::FilePath get_component_binary_path() { return component_binary_path_; }
|
||||
|
||||
void set_component_ready_for_testing(
|
||||
const base::FilePath& component_binary_path) {
|
||||
component_binary_path_ = component_binary_path;
|
||||
}
|
||||
|
||||
private:
|
||||
friend class component_updater::ScreenAIComponentInstallerPolicy;
|
||||
friend class ScreenAIInstallStateTest;
|
||||
|
||||
void SetComponentReady();
|
||||
void SetComponentReady(const base::FilePath& component_binary_path);
|
||||
|
||||
bool component_ready_ = false;
|
||||
base::FilePath component_binary_path_;
|
||||
|
||||
std::vector<Observer*> observers_;
|
||||
};
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
#include "components/services/screen_ai/public/cpp/screen_ai_install_state.h"
|
||||
|
||||
#include "base/files/file_path.h"
|
||||
#include "base/scoped_observation.h"
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
|
||||
@ -17,7 +18,10 @@ class ScreenAIInstallStateTest : public testing::Test,
|
||||
}
|
||||
|
||||
void MakeComponentReady() {
|
||||
ScreenAIInstallState::GetInstance()->SetComponentReady();
|
||||
// The passed file path is not used and just indicates that the component
|
||||
// exists.
|
||||
ScreenAIInstallState::GetInstance()->SetComponentReady(
|
||||
base::FilePath(FILE_PATH_LITERAL("tmp")));
|
||||
}
|
||||
|
||||
void ComponentReady() override { component_ready_received_ = true; }
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
#include "components/services/screen_ai/public/cpp/screen_ai_service_router.h"
|
||||
|
||||
#include "base/files/file_path.h"
|
||||
#include "components/services/screen_ai/public/cpp/screen_ai_install_state.h"
|
||||
#include "content/public/browser/service_process_host.h"
|
||||
|
||||
@ -46,11 +47,20 @@ void ScreenAIServiceRouter::LaunchIfNotRunning() {
|
||||
return;
|
||||
}
|
||||
|
||||
base::FilePath library_path =
|
||||
ScreenAIInstallState::GetInstance()->get_component_binary_path();
|
||||
|
||||
// TODO(https://crbug.com/1278249): Make sure the library is loaded from
|
||||
// |library_path| and component updater doesn't download a new version
|
||||
// during sandbox creation.
|
||||
content::ServiceProcessHost::Launch(
|
||||
screen_ai_service_.BindNewPipeAndPassReceiver(),
|
||||
content::ServiceProcessHost::Options()
|
||||
.WithDisplayName("Screen AI Service")
|
||||
.Pass());
|
||||
|
||||
if (screen_ai_service_.is_bound())
|
||||
screen_ai_service_->LoadLibrary(library_path);
|
||||
}
|
||||
|
||||
} // namespace screen_ai
|
||||
|
@ -5,8 +5,10 @@
|
||||
#include "components/services/screen_ai/public/cpp/utilities.h"
|
||||
|
||||
#include "base/files/file_enumerator.h"
|
||||
#include "base/files/file_path.h"
|
||||
#include "base/files/file_util.h"
|
||||
#include "base/path_service.h"
|
||||
#include "build/build_config.h"
|
||||
#include "components/component_updater/component_updater_paths.h"
|
||||
|
||||
namespace screen_ai {
|
||||
@ -16,17 +18,11 @@ const base::FilePath::CharType kScreenAISubDirName[] =
|
||||
FILE_PATH_LITERAL("screen_ai");
|
||||
|
||||
const base::FilePath::CharType kScreenAIComponentBinaryName[] =
|
||||
FILE_PATH_LITERAL("libchrome_screen_ai.so");
|
||||
|
||||
enum {
|
||||
PATH_START = 13000,
|
||||
|
||||
// Note that this value is not kept between sessions or shared between
|
||||
// processes.
|
||||
PATH_SCREEN_AI_LIBRARY_BINARY,
|
||||
|
||||
PATH_END
|
||||
};
|
||||
#if BUILDFLAG(IS_WIN)
|
||||
FILE_PATH_LITERAL("chrome_screen_ai.dll");
|
||||
#else
|
||||
FILE_PATH_LITERAL("libchromescreenai.so");
|
||||
#endif
|
||||
|
||||
} // namespace
|
||||
|
||||
@ -34,6 +30,10 @@ base::FilePath GetRelativeInstallDir() {
|
||||
return base::FilePath(kScreenAISubDirName);
|
||||
}
|
||||
|
||||
base::FilePath GetComponentBinaryFileName() {
|
||||
return base::FilePath(kScreenAIComponentBinaryName);
|
||||
}
|
||||
|
||||
base::FilePath GetComponentDir() {
|
||||
base::FilePath components_dir;
|
||||
base::PathService::Get(component_updater::DIR_COMPONENT_USER,
|
||||
@ -68,14 +68,4 @@ base::FilePath GetLatestComponentBinaryPath() {
|
||||
return component_path;
|
||||
}
|
||||
|
||||
void StoreComponentBinaryPath(const base::FilePath& path) {
|
||||
base::PathService::Override(PATH_SCREEN_AI_LIBRARY_BINARY, path);
|
||||
}
|
||||
|
||||
base::FilePath GetStoredComponentBinaryPath() {
|
||||
base::FilePath path;
|
||||
base::PathService::Get(PATH_SCREEN_AI_LIBRARY_BINARY, &path);
|
||||
return path;
|
||||
}
|
||||
|
||||
} // namespace screen_ai
|
@ -18,13 +18,8 @@ base::FilePath GetRelativeInstallDir();
|
||||
// Returns the folder in which ScreenAI component is installed.
|
||||
base::FilePath GetComponentDir();
|
||||
|
||||
// Stores the path to the component binary. This value is kept in memory and is
|
||||
// not kept between sessions or shared between processes.
|
||||
void StoreComponentBinaryPath(const base::FilePath& path);
|
||||
|
||||
// Returns the component binary path if it is already stored by
|
||||
// |StoreComponentBinaryPath|.
|
||||
base::FilePath GetStoredComponentBinaryPath();
|
||||
// Returns the file name of component binary.
|
||||
base::FilePath GetComponentBinaryFileName();
|
||||
|
||||
} // namespace screen_ai
|
||||
#endif // COMPONENTS_SERVICES_SCREEN_AI_PUBLIC_CPP_UTILITIES_H_
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
module screen_ai.mojom;
|
||||
|
||||
import "mojo/public/mojom/base/file_path.mojom";
|
||||
import "sandbox/policy/mojom/sandbox.mojom";
|
||||
import "skia/public/mojom/bitmap.mojom";
|
||||
import "ui/accessibility/mojom/ax_tree_id.mojom";
|
||||
@ -53,6 +54,11 @@ interface Screen2xMainContentExtractor {
|
||||
// returns the main content of the tree.
|
||||
[ServiceSandbox=sandbox.mojom.Sandbox.kScreenAI]
|
||||
interface ScreenAIService {
|
||||
// Triggers the service to load and initialize the Screen AI library at
|
||||
// |library_path|. This should be called from the browser process and be
|
||||
// eventually replaced by passing file handles.
|
||||
LoadLibrary(mojo_base.mojom.FilePath library_path);
|
||||
|
||||
// Binds a new annotator to the service.
|
||||
BindAnnotator(pending_receiver<ScreenAIAnnotator> annotator);
|
||||
|
||||
|
@ -34,7 +34,6 @@ bool ScreenAIPreSandboxHook(sandbox::policy::SandboxLinux::Options options) {
|
||||
VLOG(2) << "Screen AI library loaded pre-sandboxing:" << library_path;
|
||||
}
|
||||
}
|
||||
screen_ai::StoreComponentBinaryPath(library_path);
|
||||
|
||||
auto* instance = sandbox::policy::SandboxLinux::GetInstance();
|
||||
|
||||
|
@ -4,10 +4,16 @@
|
||||
|
||||
#include "components/services/screen_ai/screen_ai_service_impl.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "base/check.h"
|
||||
#include "base/command_line.h"
|
||||
#include "base/files/file_path.h"
|
||||
#include "base/notreached.h"
|
||||
#include "base/process/process.h"
|
||||
#include "base/scoped_native_library.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "build/build_config.h"
|
||||
#include "components/services/screen_ai/proto/proto_convertor.h"
|
||||
#include "components/services/screen_ai/public/cpp/utilities.h"
|
||||
#include "components/services/screen_ai/screen_ai_ax_tree_serializer.h"
|
||||
@ -20,21 +26,6 @@ namespace screen_ai {
|
||||
|
||||
namespace {
|
||||
|
||||
base::FilePath GetLibraryFilePath() {
|
||||
base::FilePath library_path = GetStoredComponentBinaryPath();
|
||||
|
||||
if (!library_path.empty())
|
||||
return library_path;
|
||||
|
||||
// Binary file path is set while setting the sandbox on Linux, or the first
|
||||
// time this function is called. So in all other cases we need to look for
|
||||
// the library binary in its component folder.
|
||||
library_path = GetLatestComponentBinaryPath();
|
||||
StoreComponentBinaryPath(library_path);
|
||||
|
||||
return library_path;
|
||||
}
|
||||
|
||||
std::string MakeString(const char* content, uint32_t length) {
|
||||
DCHECK(content);
|
||||
DCHECK(length);
|
||||
@ -49,18 +40,24 @@ std::string MakeString(const char* content, uint32_t length) {
|
||||
|
||||
ScreenAIService::ScreenAIService(
|
||||
mojo::PendingReceiver<mojom::ScreenAIService> receiver)
|
||||
: library_(GetLibraryFilePath()),
|
||||
init_function_(
|
||||
reinterpret_cast<InitFunction>(library_.GetFunctionPointer("Init"))),
|
||||
annotate_function_(reinterpret_cast<AnnotateFunction>(
|
||||
library_.GetFunctionPointer("Annotate"))),
|
||||
extract_main_content_function_(
|
||||
reinterpret_cast<ExtractMainContentFunction>(
|
||||
library_.GetFunctionPointer("ExtractMainContent"))),
|
||||
receiver_(this, std::move(receiver)) {
|
||||
DCHECK(init_function_ && annotate_function_ &&
|
||||
extract_main_content_function_);
|
||||
if (!CallLibraryInitFunction()) {
|
||||
: receiver_(this, std::move(receiver)) {}
|
||||
|
||||
void ScreenAIService::LoadLibrary(const base::FilePath& library_path) {
|
||||
library_ = base::ScopedNativeLibrary(library_path);
|
||||
init_function_ =
|
||||
reinterpret_cast<InitFunction>(library_.GetFunctionPointer("Init"));
|
||||
extract_main_content_function_ = reinterpret_cast<ExtractMainContentFunction>(
|
||||
library_.GetFunctionPointer("ExtractMainContent"));
|
||||
DCHECK(init_function_ && extract_main_content_function_);
|
||||
// TODO(https://crbug.com/1278249): Enable when ScreenAI is supported on
|
||||
// Windows.
|
||||
#if !BUILDFLAG(IS_WIN)
|
||||
annotate_function_ = reinterpret_cast<AnnotateFunction>(
|
||||
library_.GetFunctionPointer("Annotate"));
|
||||
DCHECK(annotate_function_);
|
||||
#endif
|
||||
|
||||
if (!CallLibraryInitFunction(library_path.DirName())) {
|
||||
// TODO(https://crbug.com/1278249): Add UMA metrics to monitor failures.
|
||||
VLOG(0) << "Screen AI library initialization failed.";
|
||||
base::Process::TerminateCurrentProcessImmediately(-1);
|
||||
@ -68,16 +65,20 @@ ScreenAIService::ScreenAIService(
|
||||
}
|
||||
|
||||
NO_SANITIZE("cfi-icall")
|
||||
bool ScreenAIService::CallLibraryInitFunction() {
|
||||
return init_function_(
|
||||
/*init_visual_annotations = */ features::
|
||||
IsScreenAIVisualAnnotationsEnabled() ||
|
||||
features::IsPdfOcrEnabled(),
|
||||
/*init_main_content_extraction = */
|
||||
features::IsReadAnythingWithScreen2xEnabled(),
|
||||
/*debug_mode = */ features::IsScreenAIDebugModeEnabled(),
|
||||
/*models_path = */
|
||||
GetLibraryFilePath().DirName().MaybeAsASCII().c_str());
|
||||
bool ScreenAIService::CallLibraryInitFunction(
|
||||
const base::FilePath& models_path) {
|
||||
bool init_main_content_extraction =
|
||||
features::IsReadAnythingWithScreen2xEnabled();
|
||||
bool init_visual_annotations;
|
||||
#if BUILDFLAG(IS_WIN)
|
||||
init_visual_annotations = false;
|
||||
#else
|
||||
init_visual_annotations = features::IsScreenAIVisualAnnotationsEnabled() ||
|
||||
features::IsPdfOcrEnabled();
|
||||
#endif
|
||||
return init_function_(init_visual_annotations, init_main_content_extraction,
|
||||
features::IsScreenAIDebugModeEnabled(),
|
||||
models_path.MaybeAsASCII().c_str());
|
||||
}
|
||||
|
||||
ScreenAIService::~ScreenAIService() = default;
|
||||
@ -148,7 +149,13 @@ bool ScreenAIService::CallLibraryAnnotateFunction(
|
||||
const SkBitmap& image,
|
||||
char*& annotation_proto,
|
||||
uint32_t& annotation_proto_length) {
|
||||
#if BUILDFLAG(IS_WIN)
|
||||
NOTIMPLEMENTED();
|
||||
return false;
|
||||
#else
|
||||
DCHECK(annotate_function_);
|
||||
return annotate_function_(image, annotation_proto, annotation_proto_length);
|
||||
#endif
|
||||
}
|
||||
|
||||
void ScreenAIService::ExtractMainContent(const ui::AXTreeUpdate& snapshot,
|
||||
@ -182,6 +189,7 @@ bool ScreenAIService::CallLibraryExtractMainContentFunction(
|
||||
const uint32_t serialized_snapshot_length,
|
||||
int32_t*& node_ids,
|
||||
uint32_t& nodes_count) {
|
||||
DCHECK(extract_main_content_function_);
|
||||
return extract_main_content_function_(
|
||||
serialized_snapshot, serialized_snapshot_length, node_ids, nodes_count);
|
||||
}
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "base/callback.h"
|
||||
#include "base/files/file_path.h"
|
||||
#include "base/scoped_native_library.h"
|
||||
#include "build/build_config.h"
|
||||
#include "components/services/screen_ai/public/mojom/screen_ai_service.mojom.h"
|
||||
#include "mojo/public/cpp/bindings/pending_remote.h"
|
||||
#include "mojo/public/cpp/bindings/receiver.h"
|
||||
@ -44,6 +45,9 @@ class ScreenAIService : public mojom::ScreenAIService,
|
||||
void ExtractMainContent(const ui::AXTreeUpdate& snapshot,
|
||||
ContentExtractionCallback callback) override;
|
||||
|
||||
// mojom::ScreenAIService:
|
||||
void LoadLibrary(const base::FilePath& library_path) override;
|
||||
|
||||
// mojom::ScreenAIService:
|
||||
void BindAnnotator(
|
||||
mojo::PendingReceiver<mojom::ScreenAIAnnotator> annotator) override;
|
||||
@ -59,7 +63,7 @@ class ScreenAIService : public mojom::ScreenAIService,
|
||||
|
||||
// Calls |init_function_| and returns the result.
|
||||
// Library function calls are isloated to have specific compiler directives.
|
||||
bool CallLibraryInitFunction();
|
||||
bool CallLibraryInitFunction(const base::FilePath& models_path);
|
||||
|
||||
// Calls |annotate_function_| and returns the result.
|
||||
// Library function calls are isloated to have specific compiler directives.
|
||||
@ -82,8 +86,9 @@ class ScreenAIService : public mojom::ScreenAIService,
|
||||
bool /*init_main_content_extraction*/,
|
||||
bool /*debug_mode*/,
|
||||
const char* /*models_path*/);
|
||||
InitFunction init_function_;
|
||||
InitFunction init_function_ = nullptr;
|
||||
|
||||
#if !BUILDFLAG(IS_WIN)
|
||||
// Sends the given bitmap to ScreenAI pipeline and returns visual annotations.
|
||||
// The annotations will be returned as a serialized VisualAnnotation proto.
|
||||
// `serialized_visual_annotation` will be allocated for the output and the
|
||||
@ -92,7 +97,8 @@ class ScreenAIService : public mojom::ScreenAIService,
|
||||
const SkBitmap& /*bitmap*/,
|
||||
char*& /*serialized_visual_annotation*/,
|
||||
uint32_t& /*serialized_visual_annotation_length*/);
|
||||
AnnotateFunction annotate_function_;
|
||||
AnnotateFunction annotate_function_ = nullptr;
|
||||
#endif
|
||||
|
||||
// Passes the given accessibility tree proto to Screen2x pipeline and returns
|
||||
// the main content ids.
|
||||
@ -104,7 +110,7 @@ class ScreenAIService : public mojom::ScreenAIService,
|
||||
uint32_t /*serialized_view_hierarchy_length*/,
|
||||
int32_t*& /*&content_node_ids*/,
|
||||
uint32_t& /*content_node_ids_length*/);
|
||||
ExtractMainContentFunction extract_main_content_function_;
|
||||
ExtractMainContentFunction extract_main_content_function_ = nullptr;
|
||||
|
||||
mojo::Receiver<mojom::ScreenAIService> receiver_;
|
||||
|
||||
@ -114,7 +120,8 @@ class ScreenAIService : public mojom::ScreenAIService,
|
||||
// The client that can receive annotator update messages.
|
||||
mojo::Remote<mojom::ScreenAIAnnotatorClient> screen_ai_annotator_client_;
|
||||
|
||||
// The set of receivers used to receive messages from main content extractors.
|
||||
// The set of receivers used to receive messages from main content
|
||||
// extractors.
|
||||
mojo::ReceiverSet<mojom::Screen2xMainContentExtractor>
|
||||
screen_2x_main_content_extractors_;
|
||||
};
|
||||
|
@ -2717,6 +2717,7 @@ source_set("browser") {
|
||||
"__ATLHOST_H__",
|
||||
]
|
||||
deps += [
|
||||
"//components/services/screen_ai/public/cpp:utilities",
|
||||
"//third_party/blink/public/common:font_unique_name_table_proto",
|
||||
"//third_party/iaccessible2",
|
||||
"//third_party/isimpledom",
|
||||
|
@ -18,6 +18,7 @@ include_rules = [
|
||||
"+components/services/quarantine/test_support.h",
|
||||
"+components/services/quarantine/quarantine.h",
|
||||
"+components/services/screen_ai/buildflags",
|
||||
"+components/services/screen_ai/public/cpp",
|
||||
"+components/services/storage",
|
||||
"+components/services/storage/public",
|
||||
"+components/session_manager/core",
|
||||
|
@ -2,11 +2,13 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "base/files/file_path.h"
|
||||
#include "content/browser/utility_sandbox_delegate.h"
|
||||
|
||||
#include "base/check.h"
|
||||
#include "base/feature_list.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "components/services/screen_ai/public/cpp/utilities.h"
|
||||
#include "content/public/browser/content_browser_client.h"
|
||||
#include "content/public/common/content_client.h"
|
||||
#include "content/public/common/content_switches.h"
|
||||
@ -37,8 +39,8 @@ bool AudioPreSpawnTarget(sandbox::TargetConfig* config) {
|
||||
//
|
||||
// For audio streams to create shared memory regions, lockdown level must be
|
||||
// at least USER_LIMITED and delayed integrity level INTEGRITY_LEVEL_LOW,
|
||||
// otherwise CreateFileMapping() will fail with error code ERROR_ACCESS_DENIED
|
||||
// (0x5).
|
||||
// otherwise CreateFileMapping() will fail with error code
|
||||
// ERROR_ACCESS_DENIED (0x5).
|
||||
//
|
||||
// For audio input streams to use ISimpleAudioVolume interface, lockdown
|
||||
// level must be set to USER_NON_ADMIN, otherwise
|
||||
@ -192,6 +194,34 @@ bool XrCompositingPreSpawnTarget(sandbox::TargetConfig* config,
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ScreenAIPreSpawnTarget(sandbox::TargetConfig* config,
|
||||
sandbox::mojom::Sandbox sandbox_type) {
|
||||
DCHECK(!config->IsConfigured());
|
||||
|
||||
auto result = config->SetTokenLevel(sandbox::USER_RESTRICTED_SAME_ACCESS,
|
||||
sandbox::USER_LOCKDOWN);
|
||||
if (result != sandbox::SBOX_ALL_OK)
|
||||
return false;
|
||||
|
||||
result = sandbox::policy::SandboxWin::SetJobLevel(
|
||||
sandbox_type, sandbox::JobLevel::kLimitedUser, 0, config);
|
||||
if (result != sandbox::SBOX_ALL_OK)
|
||||
return false;
|
||||
|
||||
// TODO(https://crbug.com/1278249): [LAUNCH BLOCKER] Remove this path and
|
||||
// instead open files and send handles to the binary.
|
||||
base::FilePath library_path = screen_ai::GetLatestComponentBinaryPath();
|
||||
if (library_path.empty())
|
||||
return false;
|
||||
base::FilePath required_path =
|
||||
library_path.DirName().Append(FILE_PATH_LITERAL("*.*"));
|
||||
result = config->AddRule(sandbox::SubSystem::kFiles,
|
||||
sandbox::Semantics::kFilesAllowReadonly,
|
||||
required_path.value().c_str());
|
||||
return result == sandbox::SBOX_ALL_OK;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
std::string UtilitySandboxedProcessLauncherDelegate::GetSandboxTag() {
|
||||
@ -264,6 +294,11 @@ bool UtilitySandboxedProcessLauncherDelegate::PreSpawnTarget(
|
||||
return false;
|
||||
}
|
||||
|
||||
if (sandbox_type_ == sandbox::mojom::Sandbox::kScreenAI) {
|
||||
if (!ScreenAIPreSpawnTarget(config, sandbox_type_))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (sandbox_type_ == sandbox::mojom::Sandbox::kSpeechRecognition) {
|
||||
auto result = config->SetIntegrityLevel(sandbox::INTEGRITY_LEVEL_LOW);
|
||||
if (result != sandbox::SBOX_ALL_OK)
|
||||
|
@ -60,7 +60,8 @@
|
||||
#endif // BUILDFLAG(ENABLE_CROS_LIBASSISTANT)
|
||||
#endif // BUILDFLAG(IS_CHROMEOS_ASH)
|
||||
|
||||
#if BUILDFLAG(ENABLE_SCREEN_AI_SERVICE)
|
||||
#if (BUILDFLAG(ENABLE_SCREEN_AI_SERVICE) && \
|
||||
(BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)))
|
||||
#include "components/services/screen_ai/sandbox/screen_ai_sandbox_hook_linux.h" // nogncheck
|
||||
#endif
|
||||
|
||||
|
@ -759,6 +759,7 @@ ResultCode GenerateConfigForSandboxedProcess(const base::CommandLine& cmd_line,
|
||||
// Post-startup mitigations.
|
||||
mitigations = MITIGATION_DLL_SEARCH_ORDER;
|
||||
if (!cmd_line.HasSwitch(switches::kAllowThirdPartyModules) &&
|
||||
sandbox_type != Sandbox::kScreenAI &&
|
||||
sandbox_type != Sandbox::kSpeechRecognition &&
|
||||
sandbox_type != Sandbox::kMediaFoundationCdm) {
|
||||
mitigations |= MITIGATION_FORCE_MS_SIGNED_BINS;
|
||||
@ -1271,6 +1272,8 @@ std::string SandboxWin::GetSandboxTypeInEnglish(Sandbox sandbox_type) {
|
||||
#endif
|
||||
case Sandbox::kAudio:
|
||||
return "Audio";
|
||||
case Sandbox::kScreenAI:
|
||||
return "Screen AI";
|
||||
case Sandbox::kSpeechRecognition:
|
||||
return "Speech Recognition";
|
||||
case Sandbox::kPdfConversion:
|
||||
|
Reference in New Issue
Block a user