Commit 00053fb4 authored by Erik Chen's avatar Erik Chen Committed by Chromium LUCI CQ

Lacros: Temporary fix for crash in clipboard code.

The ozone implementation of clipboard integration is async. The chrome
cross-platform interface is synchronous. As a result, the ozone
implementation runs a nested message loop. This in turns causes a
variety of crashes turn to re-entrancy. See issue 1155662.

The long-term solution is to make all chrome clipboard access
asynchronous. This is tracked in issues 913422 and 443355. As a short
term solution, this CL takes the only source of crashes
(ChromePasswordManagerClient::OnPaste) and directs it to use a
synchronous crosapi method rather than the ozone clipboard.

This CL also creates the helper class crosapi::ScopedAllowSyncCall to
allow crosapi OWNERs to audit access to synchronous crosapi calls,
rather than mojo OWNERs.

Change-Id: Ie419e5102bfe67daeafbef4218cfd3444c4fee88
Bug: 1155662
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2575879Reviewed-by: default avatarJan Wilken Dörrie <jdoerrie@chromium.org>
Reviewed-by: default avatarCaroline Rising <corising@chromium.org>
Reviewed-by: default avatarJames Cook <jamescook@chromium.org>
Reviewed-by: default avatarKen Rockot <rockot@google.com>
Commit-Queue: Erik Chen <erikchen@chromium.org>
Cr-Commit-Position: refs/heads/master@{#837812}
parent f19421f5
...@@ -1052,6 +1052,8 @@ source_set("chromeos") { ...@@ -1052,6 +1052,8 @@ source_set("chromeos") {
"crosapi/browser_util.h", "crosapi/browser_util.h",
"crosapi/cert_database_ash.cc", "crosapi/cert_database_ash.cc",
"crosapi/cert_database_ash.h", "crosapi/cert_database_ash.h",
"crosapi/clipboard_ash.cc",
"crosapi/clipboard_ash.h",
"crosapi/environment_provider.cc", "crosapi/environment_provider.cc",
"crosapi/environment_provider.h", "crosapi/environment_provider.h",
"crosapi/fake_browser_manager.cc", "crosapi/fake_browser_manager.cc",
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include "chrome/browser/chromeos/crosapi/account_manager_ash.h" #include "chrome/browser/chromeos/crosapi/account_manager_ash.h"
#include "chrome/browser/chromeos/crosapi/browser_manager.h" #include "chrome/browser/chromeos/crosapi/browser_manager.h"
#include "chrome/browser/chromeos/crosapi/cert_database_ash.h" #include "chrome/browser/chromeos/crosapi/cert_database_ash.h"
#include "chrome/browser/chromeos/crosapi/clipboard_ash.h"
#include "chrome/browser/chromeos/crosapi/feedback_ash.h" #include "chrome/browser/chromeos/crosapi/feedback_ash.h"
#include "chrome/browser/chromeos/crosapi/file_manager_ash.h" #include "chrome/browser/chromeos/crosapi/file_manager_ash.h"
#include "chrome/browser/chromeos/crosapi/keystore_service_ash.h" #include "chrome/browser/chromeos/crosapi/keystore_service_ash.h"
...@@ -46,7 +47,8 @@ AshChromeServiceImpl::AshChromeServiceImpl( ...@@ -46,7 +47,8 @@ AshChromeServiceImpl::AshChromeServiceImpl(
g_browser_process->local_state())), g_browser_process->local_state())),
screen_manager_ash_(std::make_unique<ScreenManagerAsh>()), screen_manager_ash_(std::make_unique<ScreenManagerAsh>()),
cert_database_ash_(std::make_unique<CertDatabaseAsh>()), cert_database_ash_(std::make_unique<CertDatabaseAsh>()),
test_controller_ash_(std::make_unique<TestControllerAsh>()) { test_controller_ash_(std::make_unique<TestControllerAsh>()),
clipboard_ash_(std::make_unique<ClipboardAsh>()) {
// TODO(hidehiko): Remove non-critical log from here. // TODO(hidehiko): Remove non-critical log from here.
// Currently this is the signal that the connection is established. // Currently this is the signal that the connection is established.
LOG(WARNING) << "AshChromeService connected."; LOG(WARNING) << "AshChromeService connected.";
...@@ -168,6 +170,11 @@ void AshChromeServiceImpl::BindTestController( ...@@ -168,6 +170,11 @@ void AshChromeServiceImpl::BindTestController(
test_controller_ash_->BindReceiver(std::move(receiver)); test_controller_ash_->BindReceiver(std::move(receiver));
} }
void AshChromeServiceImpl::BindClipboard(
mojo::PendingReceiver<mojom::Clipboard> receiver) {
clipboard_ash_->BindReceiver(std::move(receiver));
}
void AshChromeServiceImpl::OnLacrosStartup(mojom::LacrosInfoPtr lacros_info) { void AshChromeServiceImpl::OnLacrosStartup(mojom::LacrosInfoPtr lacros_info) {
BrowserManager::Get()->set_lacros_version(lacros_info->lacros_version); BrowserManager::Get()->set_lacros_version(lacros_info->lacros_version);
} }
......
...@@ -15,6 +15,7 @@ namespace crosapi { ...@@ -15,6 +15,7 @@ namespace crosapi {
class AccountManagerAsh; class AccountManagerAsh;
class CertDatabaseAsh; class CertDatabaseAsh;
class ClipboardAsh;
class FeedbackAsh; class FeedbackAsh;
class FileManagerAsh; class FileManagerAsh;
class KeystoreServiceAsh; class KeystoreServiceAsh;
...@@ -35,6 +36,9 @@ class AshChromeServiceImpl : public mojom::AshChromeService { ...@@ -35,6 +36,9 @@ class AshChromeServiceImpl : public mojom::AshChromeService {
// crosapi::mojom::AshChromeService: // crosapi::mojom::AshChromeService:
void BindAccountManager( void BindAccountManager(
mojo::PendingReceiver<mojom::AccountManager> receiver) override; mojo::PendingReceiver<mojom::AccountManager> receiver) override;
void BindCertDatabase(
mojo::PendingReceiver<mojom::CertDatabase> receiver) override;
void BindClipboard(mojo::PendingReceiver<mojom::Clipboard> receiver) override;
void BindFileManager( void BindFileManager(
mojo::PendingReceiver<mojom::FileManager> receiver) override; mojo::PendingReceiver<mojom::FileManager> receiver) override;
void BindKeystoreService( void BindKeystoreService(
...@@ -50,8 +54,6 @@ class AshChromeServiceImpl : public mojom::AshChromeService { ...@@ -50,8 +54,6 @@ class AshChromeServiceImpl : public mojom::AshChromeService {
void BindHidManager( void BindHidManager(
mojo::PendingReceiver<device::mojom::HidManager> receiver) override; mojo::PendingReceiver<device::mojom::HidManager> receiver) override;
void BindFeedback(mojo::PendingReceiver<mojom::Feedback> receiver) override; void BindFeedback(mojo::PendingReceiver<mojom::Feedback> receiver) override;
void BindCertDatabase(
mojo::PendingReceiver<mojom::CertDatabase> receiver) override;
void OnLacrosStartup(mojom::LacrosInfoPtr lacros_info) override; void OnLacrosStartup(mojom::LacrosInfoPtr lacros_info) override;
void BindMediaSessionController( void BindMediaSessionController(
mojo::PendingReceiver<media_session::mojom::MediaControllerManager> mojo::PendingReceiver<media_session::mojom::MediaControllerManager>
...@@ -78,6 +80,7 @@ class AshChromeServiceImpl : public mojom::AshChromeService { ...@@ -78,6 +80,7 @@ class AshChromeServiceImpl : public mojom::AshChromeService {
std::unique_ptr<FeedbackAsh> feedback_ash_; std::unique_ptr<FeedbackAsh> feedback_ash_;
std::unique_ptr<CertDatabaseAsh> cert_database_ash_; std::unique_ptr<CertDatabaseAsh> cert_database_ash_;
std::unique_ptr<TestControllerAsh> test_controller_ash_; std::unique_ptr<TestControllerAsh> test_controller_ash_;
std::unique_ptr<ClipboardAsh> clipboard_ash_;
}; };
} // namespace crosapi } // namespace crosapi
......
...@@ -184,12 +184,13 @@ bool IsLacrosWindow(const aura::Window* window) { ...@@ -184,12 +184,13 @@ bool IsLacrosWindow(const aura::Window* window) {
base::flat_map<base::Token, uint32_t> GetInterfaceVersions() { base::flat_map<base::Token, uint32_t> GetInterfaceVersions() {
static_assert( static_assert(
crosapi::mojom::AshChromeService::Version_ == 9, crosapi::mojom::AshChromeService::Version_ == 10,
"if you add a new crosapi, please add it to the version map here"); "if you add a new crosapi, please add it to the version map here");
InterfaceVersions versions; InterfaceVersions versions;
AddVersion<crosapi::mojom::AccountManager>(&versions); AddVersion<crosapi::mojom::AccountManager>(&versions);
AddVersion<crosapi::mojom::AshChromeService>(&versions); AddVersion<crosapi::mojom::AshChromeService>(&versions);
AddVersion<crosapi::mojom::CertDatabase>(&versions); AddVersion<crosapi::mojom::CertDatabase>(&versions);
AddVersion<crosapi::mojom::Clipboard>(&versions);
AddVersion<crosapi::mojom::Feedback>(&versions); AddVersion<crosapi::mojom::Feedback>(&versions);
AddVersion<crosapi::mojom::FileManager>(&versions); AddVersion<crosapi::mojom::FileManager>(&versions);
AddVersion<crosapi::mojom::KeystoreService>(&versions); AddVersion<crosapi::mojom::KeystoreService>(&versions);
......
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/chromeos/crosapi/clipboard_ash.h"
#include "base/strings/utf_string_conversions.h"
#include "ui/base/clipboard/clipboard.h"
namespace crosapi {
ClipboardAsh::ClipboardAsh() = default;
ClipboardAsh::~ClipboardAsh() = default;
void ClipboardAsh::BindReceiver(
mojo::PendingReceiver<mojom::Clipboard> pending_receiver) {
receivers_.Add(this, std::move(pending_receiver));
}
void ClipboardAsh::GetCopyPasteText(GetCopyPasteTextCallback callback) {
base::string16 text;
// There is no source that appropriately represents Lacros. Use kDefault for
// now.
const ui::DataTransferEndpoint endpoint(ui::EndpointType::kDefault);
ui::Clipboard::GetForCurrentThread()->ReadText(
ui::ClipboardBuffer::kCopyPaste, &endpoint, &text);
std::move(callback).Run(base::UTF16ToUTF8(text));
}
} // namespace crosapi
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_CHROMEOS_CROSAPI_CLIPBOARD_ASH_H_
#define CHROME_BROWSER_CHROMEOS_CROSAPI_CLIPBOARD_ASH_H_
#include "base/memory/weak_ptr.h"
#include "chromeos/crosapi/mojom/clipboard.mojom.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/receiver_set.h"
namespace crosapi {
// Implements the crosapi interface for clipboard. Lives in Ash-Chrome on the UI
// thread.
//
// This class provides minimal access to ui::Clipboard. It exists as a
// short-term workaround to the problem that wayland/ozone clipboard access is
// not fully stable. See https://crbug.com/913422 and https://crbug.com/1155662
// for details.
class ClipboardAsh : public mojom::Clipboard {
public:
ClipboardAsh();
ClipboardAsh(const ClipboardAsh&) = delete;
ClipboardAsh& operator=(const ClipboardAsh&) = delete;
~ClipboardAsh() override;
void BindReceiver(mojo::PendingReceiver<mojom::Clipboard> receiver);
// crosapi::mojom::Clipboard:
void GetCopyPasteText(GetCopyPasteTextCallback callback) override;
private:
// This class supports any number of connections. This allows the client to
// have multiple, potentially thread-affine, remotes.
mojo::ReceiverSet<mojom::Clipboard> receivers_;
base::WeakPtrFactory<ClipboardAsh> weak_factory_{this};
};
} // namespace crosapi
#endif // CHROME_BROWSER_CHROMEOS_CROSAPI_CLIPBOARD_ASH_H_
include_rules = [ include_rules = [
"+chrome/browser/ui/views",
"+components/account_manager_core", "+components/account_manager_core",
] ]
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/rand_util.h"
#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/lacros/browser_test_util.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/views/frame/browser_view.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
#include "chromeos/crosapi/mojom/clipboard.mojom.h"
#include "chromeos/lacros/lacros_chrome_service_impl.h"
#include "content/public/test/browser_test.h"
#include "mojo/public/cpp/bindings/sync_call_restrictions.h"
#include "ui/aura/window.h"
#include "ui/base/clipboard/scoped_clipboard_writer.h"
class ClipboardLacrosBrowserTest : public InProcessBrowserTest {
protected:
ClipboardLacrosBrowserTest() = default;
ClipboardLacrosBrowserTest(const ClipboardLacrosBrowserTest&) = delete;
ClipboardLacrosBrowserTest& operator=(const ClipboardLacrosBrowserTest&) =
delete;
void WaitForClipboardText(const std::string& text) {
base::RunLoop run_loop;
auto look_for_clipboard_text = base::BindRepeating(
[](base::RunLoop* run_loop, std::string text) {
auto* lacros_chrome_service =
chromeos::LacrosChromeServiceImpl::Get();
std::string read_text = "";
{
mojo::ScopedAllowSyncCallForTesting allow_sync_call;
lacros_chrome_service->clipboard_remote()->GetCopyPasteText(
&read_text);
}
if (read_text == text)
run_loop->Quit();
},
&run_loop, text);
base::RepeatingTimer timer;
timer.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(1),
std::move(look_for_clipboard_text));
run_loop.Run();
}
~ClipboardLacrosBrowserTest() override = default;
};
// Tests that accessing the text of the copy-paste clipboard succeeds.
// TODO(https://crbug.com/1157314): This test is not safe to run in parallel
// with other clipboard tests since there's a single exo clipboard.
IN_PROC_BROWSER_TEST_F(ClipboardLacrosBrowserTest, GetCopyPasteText) {
auto* lacros_chrome_service = chromeos::LacrosChromeServiceImpl::Get();
ASSERT_TRUE(lacros_chrome_service);
if (!lacros_chrome_service->IsClipboardAvailable())
return;
aura::Window* window = BrowserView::GetBrowserViewForBrowser(browser())
->frame()
->GetNativeWindow();
WaitForWindowToBeAvailableInAsh(window->GetRootWindow());
SendAndWaitForMouseClick(window->GetRootWindow());
// Write some clipboard text and read it back.
std::string write_text =
base::StringPrintf("clipboard text %lu", base::RandUint64());
{
ui::ScopedClipboardWriter writer(ui::ClipboardBuffer::kCopyPaste);
writer.WriteText(base::UTF8ToUTF16(write_text));
}
WaitForClipboardText(write_text);
}
...@@ -146,6 +146,12 @@ ...@@ -146,6 +146,12 @@
#include "chrome/browser/signin/dice_web_signin_interceptor_factory.h" #include "chrome/browser/signin/dice_web_signin_interceptor_factory.h"
#endif #endif
#if BUILDFLAG(IS_CHROMEOS_LACROS)
#include "chromeos/crosapi/cpp/scoped_allow_sync_call.h"
#include "chromeos/crosapi/mojom/clipboard.mojom.h"
#include "chromeos/lacros/lacros_chrome_service_impl.h"
#endif
#if defined(OS_ANDROID) #if defined(OS_ANDROID)
using password_manager::CredentialCache; using password_manager::CredentialCache;
#endif #endif
...@@ -1305,14 +1311,39 @@ void ChromePasswordManagerClient::OnPaste() { ...@@ -1305,14 +1311,39 @@ void ChromePasswordManagerClient::OnPaste() {
<< web_contents()->GetMainFrame()->GetRenderViewHost(); << web_contents()->GetMainFrame()->GetRenderViewHost();
#endif #endif
ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread();
base::string16 text; base::string16 text;
// Given that this clipboard data read happens in the background and not bool used_crosapi_workaround = false;
// initiated by a user gesture, then the user shouldn't see a notification if #if BUILDFLAG(IS_CHROMEOS_LACROS)
// the clipboard is restricted by the rules of data leak prevention policy. // On Lacros, the ozone/wayland clipboard implementation is asynchronous by
ui::DataTransferEndpoint data_dst = ui::DataTransferEndpoint( // default and runs a nested message loop to fake synchroncity. This in turn
ui::EndpointType::kDefault, /*notify_if_restricted=*/false); // causes crashes. See https://crbug.com/1155662 for details. In the short
clipboard->ReadText(ui::ClipboardBuffer::kCopyPaste, &data_dst, &text); // term, we skip ozone/wayland entirely and use a synchronous crosapi to get
// clipboard text.
// TODO(https://crbug.com/913422): This logic can be removed once all
// clipboard APIs are async.
auto* service = chromeos::LacrosChromeServiceImpl::Get();
if (service->IsClipboardAvailable()) {
used_crosapi_workaround = true;
std::string text_utf8;
{
crosapi::ScopedAllowSyncCall allow_sync_call;
service->clipboard_remote()->GetCopyPasteText(&text_utf8);
}
text = base::UTF8ToUTF16(text_utf8);
}
#endif
if (!used_crosapi_workaround) {
ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread();
// Given that this clipboard data read happens in the background and not
// initiated by a user gesture, then the user shouldn't see a notification
// if the clipboard is restricted by the rules of data leak prevention
// policy.
ui::DataTransferEndpoint data_dst = ui::DataTransferEndpoint(
ui::EndpointType::kDefault, /*notify_if_restricted=*/false);
clipboard->ReadText(ui::ClipboardBuffer::kCopyPaste, &data_dst, &text);
}
was_on_paste_called_ = true; was_on_paste_called_ = true;
password_reuse_detection_manager_.OnPaste(std::move(text)); password_reuse_detection_manager_.OnPaste(std::move(text));
} }
......
...@@ -3225,6 +3225,7 @@ if (is_chromeos_lacros) { ...@@ -3225,6 +3225,7 @@ if (is_chromeos_lacros) {
sources = [ sources = [
"../browser/lacros/browser_test_util.cc", "../browser/lacros/browser_test_util.cc",
"../browser/lacros/browser_test_util.h", "../browser/lacros/browser_test_util.h",
"../browser/lacros/clipboard_lacros_browsertest.cc",
"../browser/lacros/file_manager_lacros_browsertest.cc", "../browser/lacros/file_manager_lacros_browsertest.cc",
"../browser/lacros/keystore_service_lacros_browsertest.cc", "../browser/lacros/keystore_service_lacros_browsertest.cc",
"../browser/lacros/media_session_lacros_browsertest.cc", "../browser/lacros/media_session_lacros_browsertest.cc",
......
...@@ -16,10 +16,13 @@ component("cpp") { ...@@ -16,10 +16,13 @@ component("cpp") {
"bitmap_util.h", "bitmap_util.h",
"crosapi_constants.cc", "crosapi_constants.cc",
"crosapi_constants.h", "crosapi_constants.h",
"scoped_allow_sync_call.cc",
"scoped_allow_sync_call.h",
] ]
configs += [ ":crosapi_implementation" ] configs += [ ":crosapi_implementation" ]
deps = [ deps = [
"//base", "//base",
"//mojo/public/cpp/bindings",
"//skia", "//skia",
] ]
} }
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chromeos/crosapi/cpp/scoped_allow_sync_call.h"
namespace crosapi {
ScopedAllowSyncCall::ScopedAllowSyncCall() = default;
ScopedAllowSyncCall::~ScopedAllowSyncCall() = default;
} // namespace crosapi
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROMEOS_CROSAPI_CPP_SCOPED_ALLOW_SYNC_CALL_H_
#define CHROMEOS_CROSAPI_CPP_SCOPED_ALLOW_SYNC_CALL_H_
#include "base/component_export.h"
#include "mojo/public/cpp/bindings/sync_call_restrictions.h"
class ChromePasswordManagerClient;
namespace crosapi {
// Chrome generally disallows sync IPC calls. Crosapi allows a small number of
// exceptions to support cross-platform code where other platforms all provide a
// synchronous implementation of a particular API. Use this sparingly.
class COMPONENT_EXPORT(CROSAPI) ScopedAllowSyncCall {
private:
// Consumers of this class must be explicitly added as a friend.
friend class ::ChromePasswordManagerClient;
ScopedAllowSyncCall();
ScopedAllowSyncCall(const ScopedAllowSyncCall&) = delete;
ScopedAllowSyncCall& operator=(const ScopedAllowSyncCall&) = delete;
~ScopedAllowSyncCall();
mojo::SyncCallRestrictions::ScopedAllowSyncCall scoped_allow_;
};
} // namespace crosapi
#endif // CHROMEOS_CROSAPI_CPP_SCOPED_ALLOW_SYNC_CALL_H_
...@@ -9,6 +9,7 @@ mojom("mojom") { ...@@ -9,6 +9,7 @@ mojom("mojom") {
"account_manager.mojom", "account_manager.mojom",
"bitmap.mojom", "bitmap.mojom",
"cert_database.mojom", "cert_database.mojom",
"clipboard.mojom",
"crosapi.mojom", "crosapi.mojom",
"feedback.mojom", "feedback.mojom",
"file_manager.mojom", "file_manager.mojom",
......
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
module crosapi.mojom;
// This interface is implemented by Ash-Chrome.
// Normally, we'd want all clipboard access to go through the Wayland clipboard
// APIs. This currently requires a major refactor to become fully functional,
// see https://crbug.com/913422 for details. This is a short-term workaround
// that provides synchronous clipboard access.
[Stable, Uuid="f2c9e4b9-8782-4b20-a8be-f3b2a3400a38"]
interface Clipboard {
// Returns the unicode contents of the clipboard copy/paste buffer, UTF-8
// encoded.
[Sync]
GetCopyPasteText@0() => (string text);
};
...@@ -6,6 +6,7 @@ module crosapi.mojom; ...@@ -6,6 +6,7 @@ module crosapi.mojom;
import "chromeos/crosapi/mojom/account_manager.mojom"; import "chromeos/crosapi/mojom/account_manager.mojom";
import "chromeos/crosapi/mojom/cert_database.mojom"; import "chromeos/crosapi/mojom/cert_database.mojom";
import "chromeos/crosapi/mojom/clipboard.mojom";
import "chromeos/crosapi/mojom/feedback.mojom"; import "chromeos/crosapi/mojom/feedback.mojom";
import "chromeos/crosapi/mojom/file_manager.mojom"; import "chromeos/crosapi/mojom/file_manager.mojom";
import "chromeos/crosapi/mojom/keystore_service.mojom"; import "chromeos/crosapi/mojom/keystore_service.mojom";
...@@ -42,8 +43,8 @@ struct LacrosInfo { ...@@ -42,8 +43,8 @@ struct LacrosInfo {
// milestone when you added it, to help us reason about compatibility between // milestone when you added it, to help us reason about compatibility between
// lacros-chrome and older ash-chrome binaries. // lacros-chrome and older ash-chrome binaries.
// //
// Next version: 10 // Next version: 11
// Next method id: 15 // Next method id: 16
[Stable, Uuid="8b79c34f-2bf8-4499-979a-b17cac522c1e"] [Stable, Uuid="8b79c34f-2bf8-4499-979a-b17cac522c1e"]
interface AshChromeService { interface AshChromeService {
// Binds Chrome OS Account Manager for Identity management. // Binds Chrome OS Account Manager for Identity management.
...@@ -51,6 +52,15 @@ interface AshChromeService { ...@@ -51,6 +52,15 @@ interface AshChromeService {
[MinVersion=4] [MinVersion=4]
BindAccountManager@7(pending_receiver<AccountManager> receiver); BindAccountManager@7(pending_receiver<AccountManager> receiver);
// Binds the CertDatabase interface for initializing certificate database in
// Lacros-Chrome.
// Added in M89.
[MinVersion=7] BindCertDatabase@12(pending_receiver<CertDatabase> receiver);
// Bind the clipboard interface to allow lacros-chrome to interact with the
// system clipboard.
[MinVersion=10] BindClipboard@15(pending_receiver<Clipboard> receiver);
// Binds the FileManager interface for showing files, folders, etc. // Binds the FileManager interface for showing files, folders, etc.
// Added in M88. // Added in M88.
[MinVersion=5] [MinVersion=5]
...@@ -104,11 +114,6 @@ interface AshChromeService { ...@@ -104,11 +114,6 @@ interface AshChromeService {
[MinVersion=6] BindMediaSessionAudioFocusDebug@11( [MinVersion=6] BindMediaSessionAudioFocusDebug@11(
pending_receiver<media_session.mojom.AudioFocusManagerDebug> receiver); pending_receiver<media_session.mojom.AudioFocusManagerDebug> receiver);
// Binds the CertDatabase interface for initializing certificate database in
// Lacros-Chrome.
// Added in M89.
[MinVersion=7] BindCertDatabase@12(pending_receiver<CertDatabase> receiver);
// Binds the test controller service, which tests can use to mutate ash. This // Binds the test controller service, which tests can use to mutate ash. This
// is not available on production devices. // is not available on production devices.
[MinVersion=9] BindTestController@14( [MinVersion=9] BindTestController@14(
......
...@@ -208,6 +208,12 @@ class LacrosChromeServiceNeverBlockingState ...@@ -208,6 +208,12 @@ class LacrosChromeServiceNeverBlockingState
ash_chrome_service_->BindFileManager(std::move(pending_receiver)); ash_chrome_service_->BindFileManager(std::move(pending_receiver));
} }
void BindClipboardReceiver(
mojo::PendingReceiver<crosapi::mojom::Clipboard> pending_receiver) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
ash_chrome_service_->BindClipboard(std::move(pending_receiver));
}
void BindMediaSessionAudioFocusReceiver( void BindMediaSessionAudioFocusReceiver(
mojo::PendingReceiver<media_session::mojom::AudioFocusManager> mojo::PendingReceiver<media_session::mojom::AudioFocusManager>
pending_receiver) { pending_receiver) {
...@@ -438,6 +444,16 @@ void LacrosChromeServiceImpl::BindReceiver( ...@@ -438,6 +444,16 @@ void LacrosChromeServiceImpl::BindReceiver(
&LacrosChromeServiceNeverBlockingState::BindTestControllerReceiver, &LacrosChromeServiceNeverBlockingState::BindTestControllerReceiver,
weak_sequenced_state_, std::move(pending_receiver))); weak_sequenced_state_, std::move(pending_receiver)));
} }
if (IsClipboardAvailable()) {
mojo::PendingReceiver<crosapi::mojom::Clipboard> pending_receiver =
clipboard_remote_.BindNewPipeAndPassReceiver();
never_blocking_sequence_->PostTask(
FROM_HERE,
base::BindOnce(
&LacrosChromeServiceNeverBlockingState::BindClipboardReceiver,
weak_sequenced_state_, std::move(pending_receiver)));
}
} }
// static // static
...@@ -516,6 +532,13 @@ bool LacrosChromeServiceImpl::IsTestControllerAvailable() { ...@@ -516,6 +532,13 @@ bool LacrosChromeServiceImpl::IsTestControllerAvailable() {
#endif #endif
} }
bool LacrosChromeServiceImpl::IsClipboardAvailable() {
base::Optional<uint32_t> version = AshChromeServiceVersion();
return version &&
version.value() >=
AshChromeService::MethodMinVersions::kBindClipboardMinVersion;
}
bool LacrosChromeServiceImpl::IsScreenManagerAvailable() { bool LacrosChromeServiceImpl::IsScreenManagerAvailable() {
base::Optional<uint32_t> version = AshChromeServiceVersion(); base::Optional<uint32_t> version = AshChromeServiceVersion();
return version && return version &&
......
...@@ -202,6 +202,17 @@ class COMPONENT_EXPORT(CHROMEOS_LACROS) LacrosChromeServiceImpl { ...@@ -202,6 +202,17 @@ class COMPONENT_EXPORT(CHROMEOS_LACROS) LacrosChromeServiceImpl {
return test_controller_remote_; return test_controller_remote_;
} }
// clipboard_remote() can only be used if this method returns true.
bool IsClipboardAvailable();
// This must be called on the affine sequence. It exposes a remote that can
// be used to interface with the clipboard
mojo::Remote<crosapi::mojom::Clipboard>& clipboard_remote() {
DCHECK_CALLED_ON_VALID_SEQUENCE(affine_sequence_checker_);
DCHECK(IsClipboardAvailable());
return clipboard_remote_;
}
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
// Some clients will want to use mojo::Remotes on arbitrary sequences (e.g. // Some clients will want to use mojo::Remotes on arbitrary sequences (e.g.
// background threads). The following methods allow the client to construct a // background threads). The following methods allow the client to construct a
...@@ -295,6 +306,7 @@ class COMPONENT_EXPORT(CHROMEOS_LACROS) LacrosChromeServiceImpl { ...@@ -295,6 +306,7 @@ class COMPONENT_EXPORT(CHROMEOS_LACROS) LacrosChromeServiceImpl {
mojo::Remote<crosapi::mojom::KeystoreService> keystore_service_remote_; mojo::Remote<crosapi::mojom::KeystoreService> keystore_service_remote_;
mojo::Remote<crosapi::mojom::FileManager> file_manager_remote_; mojo::Remote<crosapi::mojom::FileManager> file_manager_remote_;
mojo::Remote<crosapi::mojom::TestController> test_controller_remote_; mojo::Remote<crosapi::mojom::TestController> test_controller_remote_;
mojo::Remote<crosapi::mojom::Clipboard> clipboard_remote_;
// This member is instantiated on the affine sequence alongside the // This member is instantiated on the affine sequence alongside the
// constructor. All subsequent invocations of this member, including // constructor. All subsequent invocations of this member, including
......
...@@ -23,6 +23,10 @@ namespace content { ...@@ -23,6 +23,10 @@ namespace content {
class DesktopCapturerLacros; class DesktopCapturerLacros;
} // namespace content } // namespace content
namespace crosapi {
class ScopedAllowSyncCall;
} // namespace crosapi
namespace ui { namespace ui {
class Compositor; class Compositor;
} // namespace ui } // namespace ui
...@@ -74,6 +78,7 @@ class COMPONENT_EXPORT(MOJO_CPP_BINDINGS) SyncCallRestrictions { ...@@ -74,6 +78,7 @@ class COMPONENT_EXPORT(MOJO_CPP_BINDINGS) SyncCallRestrictions {
// Lacros-chrome is allowed to make sync calls to ash-chrome to mimic // Lacros-chrome is allowed to make sync calls to ash-chrome to mimic
// cross-platform sync APIs. // cross-platform sync APIs.
friend class content::DesktopCapturerLacros; friend class content::DesktopCapturerLacros;
friend class crosapi::ScopedAllowSyncCall;
friend class mojo::ScopedAllowSyncCallForTesting; friend class mojo::ScopedAllowSyncCallForTesting;
// For destroying the GL context/surface that draw to a platform window before // For destroying the GL context/surface that draw to a platform window before
// the platform window is destroyed. // the platform window is destroyed.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment