Commit 85e33f87 authored by Jasmine Chen's avatar Jasmine Chen Committed by Commit Bot

VCD: Add interfaces for usage indicator integration

Adds interfaces for persistent indicator integration. This includes:
- RegisterServerWithToken to register CameraHalServer with an added
  token-based authentication mechanism.
- RegisterClientWithToken to register CameraHalClient with token.
- TokenManager which issues and authenticates unguessable tokens for
  trusted HAL clients (Chrome, Android).
- Migrates Chrome VCD to register its CameraHalClient with tokens.
- CameraHalServerCallbacks for CameraHalServer to notify
  CameraHalDispatcher of updates on the server side, including camera
  activity changes.

Refer to go/cros-camera:dd:perm for the details on the design.

Bug: b:170075468
Test: Build and deploy simplechrome. Verify Chrome with new interface
    sends IPC calls cros-camera with both the old and new interface.

Change-Id: Idd52d184b922e2df5578fd38efcf01fa13334569
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2501104
Commit-Queue: Jasmine Chen <lnishan@google.com>
Reviewed-by: default avatarRobert Sesek <rsesek@chromium.org>
Reviewed-by: default avatarGuido Urdaneta <guidou@chromium.org>
Reviewed-by: default avatarWei Lee <wtlee@chromium.org>
Cr-Commit-Position: refs/heads/master@{#827753}
parent e5ccea4e
......@@ -306,6 +306,8 @@ component("capture_lib") {
"video/chromeos/scoped_video_capture_jpeg_decoder.h",
"video/chromeos/stream_buffer_manager.cc",
"video/chromeos/stream_buffer_manager.h",
"video/chromeos/token_manager.cc",
"video/chromeos/token_manager.h",
"video/chromeos/vendor_tag_ops_delegate.cc",
"video/chromeos/vendor_tag_ops_delegate.h",
"video/chromeos/video_capture_device_chromeos_halv3.cc",
......
......@@ -20,6 +20,7 @@
#include "base/strings/string_piece.h"
#include "base/strings/string_split.h"
#include "base/system/system_monitor.h"
#include "base/unguessable_token.h"
#include "media/capture/video/chromeos/camera_app_device_bridge_impl.h"
#include "media/capture/video/chromeos/camera_buffer_factory.h"
#include "media/capture/video/chromeos/camera_hal_dispatcher_impl.h"
......@@ -38,8 +39,11 @@ constexpr base::TimeDelta kEventWaitTimeoutSecs =
class LocalCameraClientObserver : public CameraClientObserver {
public:
explicit LocalCameraClientObserver(
scoped_refptr<CameraHalDelegate> camera_hal_delegate)
: camera_hal_delegate_(std::move(camera_hal_delegate)) {}
scoped_refptr<CameraHalDelegate> camera_hal_delegate,
cros::mojom::CameraClientType type,
base::UnguessableToken auth_token)
: CameraClientObserver(type, std::move(auth_token)),
camera_hal_delegate_(std::move(camera_hal_delegate)) {}
void OnChannelCreated(
mojo::PendingRemote<cros::mojom::CameraModule> camera_module) override {
......@@ -117,7 +121,8 @@ base::flat_set<int32_t> GetAvailableFramerates(
CameraHalDelegate::CameraHalDelegate(
scoped_refptr<base::SingleThreadTaskRunner> ipc_task_runner)
: camera_module_has_been_set_(
: authenticated_(false),
camera_module_has_been_set_(
base::WaitableEvent::ResetPolicy::MANUAL,
base::WaitableEvent::InitialState::NOT_SIGNALED),
builtin_camera_info_updated_(
......@@ -138,9 +143,27 @@ CameraHalDelegate::CameraHalDelegate(
CameraHalDelegate::~CameraHalDelegate() = default;
void CameraHalDelegate::RegisterCameraClient() {
CameraHalDispatcherImpl::GetInstance()->AddClientObserver(
std::make_unique<LocalCameraClientObserver>(this));
bool CameraHalDelegate::RegisterCameraClient() {
auto* dispatcher = CameraHalDispatcherImpl::GetInstance();
auto type = cros::mojom::CameraClientType::CHROME;
dispatcher->AddClientObserver(
std::make_unique<LocalCameraClientObserver>(
this, type, dispatcher->GetTokenForTrustedClient(type)),
base::BindOnce(&CameraHalDelegate::OnRegisteredCameraHalClient,
base::Unretained(this)));
camera_hal_client_registered_.Wait();
return authenticated_;
}
void CameraHalDelegate::OnRegisteredCameraHalClient(int32_t result) {
if (result != 0) {
LOG(ERROR) << "Failed to register camera HAL client";
camera_hal_client_registered_.Signal();
return;
}
VLOG(1) << "Registered camera HAL client";
authenticated_ = true;
camera_hal_client_registered_.Signal();
}
void CameraHalDelegate::SetCameraModule(
......
......@@ -47,7 +47,8 @@ class CAPTURE_EXPORT CameraHalDelegate final
scoped_refptr<base::SingleThreadTaskRunner> ipc_task_runner);
// Registers the camera client observer to the CameraHalDispatcher instance.
void RegisterCameraClient();
// Returns true if successful, false if failed (e.g., authentication failure).
bool RegisterCameraClient();
void SetCameraModule(
mojo::PendingRemote<cros::mojom::CameraModule> camera_module);
......@@ -94,6 +95,8 @@ class CAPTURE_EXPORT CameraHalDelegate final
~CameraHalDelegate() final;
void OnRegisteredCameraHalClient(int32_t result);
void GetSupportedFormats(int camera_id,
VideoCaptureFormats* supported_formats);
......@@ -144,6 +147,9 @@ class CAPTURE_EXPORT CameraHalDelegate final
void TorchModeStatusChange(int32_t camera_id,
cros::mojom::TorchModeStatus new_status) final;
base::WaitableEvent camera_hal_client_registered_;
bool authenticated_;
base::WaitableEvent camera_module_has_been_set_;
// Signaled when |num_builtin_cameras_| and |camera_info_| are updated.
......
......@@ -50,7 +50,8 @@ std::string GenerateRandomToken() {
// to here, and the write side will be closed in such a case.
bool WaitForSocketReadable(int raw_socket_fd, int raw_cancel_fd) {
struct pollfd fds[2] = {
{raw_socket_fd, POLLIN, 0}, {raw_cancel_fd, POLLIN, 0},
{raw_socket_fd, POLLIN, 0},
{raw_cancel_fd, POLLIN, 0},
};
if (HANDLE_EINTR(poll(fds, base::size(fds), -1)) <= 0) {
......@@ -70,8 +71,11 @@ bool WaitForSocketReadable(int raw_socket_fd, int raw_cancel_fd) {
class MojoCameraClientObserver : public CameraClientObserver {
public:
explicit MojoCameraClientObserver(
mojo::PendingRemote<cros::mojom::CameraHalClient> client)
: client_(std::move(client)) {}
mojo::PendingRemote<cros::mojom::CameraHalClient> client,
cros::mojom::CameraClientType type,
base::UnguessableToken auth_token)
: CameraClientObserver(type, std::move(auth_token)),
client_(std::move(client)) {}
void OnChannelCreated(
mojo::PendingRemote<cros::mojom::CameraModule> camera_module) override {
......@@ -132,14 +136,16 @@ bool CameraHalDispatcherImpl::Start(
}
void CameraHalDispatcherImpl::AddClientObserver(
std::unique_ptr<CameraClientObserver> observer) {
std::unique_ptr<CameraClientObserver> observer,
base::OnceCallback<void(int32_t)> result_callback) {
// If |proxy_thread_| fails to start in Start() then CameraHalDelegate will
// not be created, and this function will not be called.
DCHECK(proxy_thread_.IsRunning());
proxy_thread_.task_runner()->PostTask(
FROM_HERE,
base::BindOnce(&CameraHalDispatcherImpl::AddClientObserverOnProxyThread,
base::Unretained(this), std::move(observer)));
base::Unretained(this), std::move(observer),
std::move(result_callback)));
}
bool CameraHalDispatcherImpl::IsStarted() {
......@@ -149,7 +155,8 @@ bool CameraHalDispatcherImpl::IsStarted() {
CameraHalDispatcherImpl::CameraHalDispatcherImpl()
: proxy_thread_("CameraProxyThread"),
blocking_io_thread_("CameraBlockingIOThread") {
blocking_io_thread_("CameraBlockingIOThread"),
camera_hal_server_callbacks_(this) {
// This event is for adding camera category to categories list.
TRACE_EVENT0("camera", "CameraHalDispatcherImpl");
base::trace_event::TraceLog::GetInstance()->AddEnabledStateObserver(this);
......@@ -171,6 +178,19 @@ CameraHalDispatcherImpl::~CameraHalDispatcherImpl() {
void CameraHalDispatcherImpl::RegisterServer(
mojo::PendingRemote<cros::mojom::CameraHalServer> camera_hal_server) {
DCHECK(proxy_task_runner_->BelongsToCurrentThread());
// TODO(b/170075468): Reject this call once Chrome OS uses
// RegisterServerWithToken.
auto temporary_token = base::UnguessableToken::Create();
RegisterServerWithToken(std::move(camera_hal_server), temporary_token,
base::DoNothing());
}
void CameraHalDispatcherImpl::RegisterServerWithToken(
mojo::PendingRemote<cros::mojom::CameraHalServer> camera_hal_server,
const base::UnguessableToken& token,
RegisterServerWithTokenCallback callback) {
DCHECK(proxy_task_runner_->BelongsToCurrentThread());
// TODO(b/170075468): Authenticate the token.
if (camera_hal_server_) {
LOG(ERROR) << "Camera HAL server is already registered";
......@@ -181,6 +201,8 @@ void CameraHalDispatcherImpl::RegisterServer(
base::BindOnce(&CameraHalDispatcherImpl::OnCameraHalServerConnectionError,
base::Unretained(this)));
VLOG(1) << "Camera HAL server registered";
std::move(callback).Run(
0, camera_hal_server_callbacks_.BindNewPipeAndPassRemote());
// Set up the Mojo channels for clients which registered before the server
// registers.
......@@ -191,13 +213,29 @@ void CameraHalDispatcherImpl::RegisterServer(
void CameraHalDispatcherImpl::RegisterClient(
mojo::PendingRemote<cros::mojom::CameraHalClient> client) {
DCHECK(proxy_task_runner_->BelongsToCurrentThread());
// TODO(b/170075468): Reject this call once we've migrated all camera clients.
auto temporary_token = base::UnguessableToken::Create();
RegisterClientWithToken(std::move(client),
cros::mojom::CameraClientType::UNKNOWN,
temporary_token, base::DoNothing());
}
void CameraHalDispatcherImpl::RegisterClientWithToken(
mojo::PendingRemote<cros::mojom::CameraHalClient> client,
cros::mojom::CameraClientType type,
const base::UnguessableToken& auth_token,
RegisterClientWithTokenCallback callback) {
// RegisterClient can be called locally by ArcCameraBridge. Unretained
// reference is safe here because CameraHalDispatcherImpl owns
// |proxy_thread_|.
base::UnguessableToken client_auth_token = auth_token;
proxy_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&CameraHalDispatcherImpl::RegisterClientOnProxyThread,
base::Unretained(this), std::move(client)));
base::BindOnce(
&CameraHalDispatcherImpl::RegisterClientWithTokenOnProxyThread,
base::Unretained(this), std::move(client), type,
std::move(client_auth_token), std::move(callback)));
}
void CameraHalDispatcherImpl::GetJpegDecodeAccelerator(
......@@ -212,6 +250,20 @@ void CameraHalDispatcherImpl::GetJpegEncodeAccelerator(
jea_factory_.Run(std::move(jea_receiver));
}
void CameraHalDispatcherImpl::CameraDeviceActivityChange(
int32_t camera_id,
bool opened,
cros::mojom::CameraClientType type) {
// TODO(b/170075468): Implement.
VLOG(1) << type << (opened ? " opened " : " closed ") << "camera "
<< camera_id;
}
base::UnguessableToken CameraHalDispatcherImpl::GetTokenForTrustedClient(
cros::mojom::CameraClientType type) {
return token_manager_.GetTokenForTrustedClient(type);
}
void CameraHalDispatcherImpl::OnTraceLogEnabled() {
proxy_task_runner_->PostTask(
FROM_HERE,
......@@ -347,33 +399,46 @@ void CameraHalDispatcherImpl::StartServiceLoop(base::ScopedFD socket_fd,
}
}
void CameraHalDispatcherImpl::RegisterClientOnProxyThread(
mojo::PendingRemote<cros::mojom::CameraHalClient> client) {
void CameraHalDispatcherImpl::RegisterClientWithTokenOnProxyThread(
mojo::PendingRemote<cros::mojom::CameraHalClient> client,
cros::mojom::CameraClientType type,
base::UnguessableToken auth_token,
RegisterClientWithTokenCallback callback) {
DCHECK(proxy_task_runner_->BelongsToCurrentThread());
auto client_observer =
std::make_unique<MojoCameraClientObserver>(std::move(client));
auto client_observer = std::make_unique<MojoCameraClientObserver>(
std::move(client), type, std::move(auth_token));
client_observer->client().set_disconnect_handler(base::BindOnce(
&CameraHalDispatcherImpl::OnCameraHalClientConnectionError,
base::Unretained(this), base::Unretained(client_observer.get())));
AddClientObserver(std::move(client_observer));
VLOG(1) << "Camera HAL client registered";
AddClientObserver(std::move(client_observer), std::move(callback));
}
void CameraHalDispatcherImpl::AddClientObserverOnProxyThread(
std::unique_ptr<CameraClientObserver> observer) {
std::unique_ptr<CameraClientObserver> observer,
base::OnceCallback<void(int32_t)> result_callback) {
DCHECK(proxy_task_runner_->BelongsToCurrentThread());
if (!token_manager_.AuthenticateClient(observer->GetType(),
observer->GetAuthToken())) {
LOG(ERROR) << "Failed to authenticate camera client observer";
std::move(result_callback).Run(-EPERM);
return;
}
if (camera_hal_server_) {
EstablishMojoChannel(observer.get());
}
client_observers_.insert(std::move(observer));
std::move(result_callback).Run(0);
VLOG(1) << "Camera HAL client registered";
}
void CameraHalDispatcherImpl::EstablishMojoChannel(
CameraClientObserver* client_observer) {
DCHECK(proxy_task_runner_->BelongsToCurrentThread());
mojo::PendingRemote<cros::mojom::CameraModule> camera_module;
const auto& type = client_observer->GetType();
VLOG(1) << "Establishing server channel for " << type;
camera_hal_server_->CreateChannel(
camera_module.InitWithNewPipeAndPassReceiver());
camera_module.InitWithNewPipeAndPassReceiver(), type);
client_observer->OnChannelCreated(std::move(camera_module));
}
......@@ -390,6 +455,7 @@ void CameraHalDispatcherImpl::OnCameraHalServerConnectionError() {
DCHECK(proxy_task_runner_->BelongsToCurrentThread());
VLOG(1) << "Camera HAL server connection lost";
camera_hal_server_.reset();
camera_hal_server_callbacks_.reset();
}
void CameraHalDispatcherImpl::OnCameraHalClientConnectionError(
......
......@@ -12,10 +12,12 @@
#include "base/files/scoped_file.h"
#include "base/memory/singleton.h"
#include "base/threading/thread.h"
#include "base/unguessable_token.h"
#include "components/chromeos_camera/common/jpeg_encode_accelerator.mojom.h"
#include "components/chromeos_camera/common/mjpeg_decode_accelerator.mojom.h"
#include "media/capture/capture_export.h"
#include "media/capture/video/chromeos/mojom/cros_camera_service.mojom.h"
#include "media/capture/video/chromeos/token_manager.h"
#include "media/capture/video/chromeos/video_capture_device_factory_chromeos.h"
#include "media/capture/video/video_capture_device_factory.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
......@@ -38,9 +40,19 @@ using MojoJpegEncodeAcceleratorFactoryCB = base::RepeatingCallback<void(
class CAPTURE_EXPORT CameraClientObserver {
public:
CameraClientObserver(cros::mojom::CameraClientType type,
base::UnguessableToken auth_token)
: type_(type), auth_token_(auth_token) {}
virtual ~CameraClientObserver();
virtual void OnChannelCreated(
mojo::PendingRemote<cros::mojom::CameraModule> camera_module) = 0;
cros::mojom::CameraClientType GetType() { return type_; }
const base::UnguessableToken GetAuthToken() { return auth_token_; }
private:
cros::mojom::CameraClientType type_;
base::UnguessableToken auth_token_;
};
// The CameraHalDispatcherImpl hosts and waits on the unix domain socket
......@@ -55,6 +67,7 @@ class CAPTURE_EXPORT CameraClientObserver {
// comments in mojo/cros_camera_service.mojom.
class CAPTURE_EXPORT CameraHalDispatcherImpl final
: public cros::mojom::CameraHalDispatcher,
public cros::mojom::CameraHalServerCallbacks,
public base::trace_event::TraceLog::EnabledStateObserver {
public:
static CameraHalDispatcherImpl* GetInstance();
......@@ -62,15 +75,25 @@ class CAPTURE_EXPORT CameraHalDispatcherImpl final
bool Start(MojoMjpegDecodeAcceleratorFactoryCB jda_factory,
MojoJpegEncodeAcceleratorFactoryCB jea_factory);
void AddClientObserver(std::unique_ptr<CameraClientObserver> observer);
void AddClientObserver(std::unique_ptr<CameraClientObserver> observer,
base::OnceCallback<void(int32_t)> result_callback);
bool IsStarted();
// CameraHalDispatcher implementations.
void RegisterServer(
mojo::PendingRemote<cros::mojom::CameraHalServer> server) final;
void RegisterServerWithToken(
mojo::PendingRemote<cros::mojom::CameraHalServer> server,
const base::UnguessableToken& token,
RegisterServerWithTokenCallback callback) final;
void RegisterClient(
mojo::PendingRemote<cros::mojom::CameraHalClient> client) final;
void RegisterClientWithToken(
mojo::PendingRemote<cros::mojom::CameraHalClient> client,
cros::mojom::CameraClientType type,
const base::UnguessableToken& auth_token,
RegisterClientWithTokenCallback callback) final;
void GetJpegDecodeAccelerator(
mojo::PendingReceiver<chromeos_camera::mojom::MjpegDecodeAccelerator>
jda_receiver) final;
......@@ -78,6 +101,14 @@ class CAPTURE_EXPORT CameraHalDispatcherImpl final
mojo::PendingReceiver<chromeos_camera::mojom::JpegEncodeAccelerator>
jea_receiver) final;
// CameraHalServerCallbacks implementations.
void CameraDeviceActivityChange(int32_t camera_id,
bool opened,
cros::mojom::CameraClientType type) final;
base::UnguessableToken GetTokenForTrustedClient(
cros::mojom::CameraClientType type);
// base::trace_event::TraceLog::EnabledStateObserver implementation.
void OnTraceLogEnabled() final;
void OnTraceLogDisabled() final;
......@@ -100,10 +131,14 @@ class CAPTURE_EXPORT CameraHalDispatcherImpl final
// Runs on |blocking_io_thread_|.
void StartServiceLoop(base::ScopedFD socket_fd, base::WaitableEvent* started);
void RegisterClientOnProxyThread(
mojo::PendingRemote<cros::mojom::CameraHalClient> client);
void RegisterClientWithTokenOnProxyThread(
mojo::PendingRemote<cros::mojom::CameraHalClient> client,
cros::mojom::CameraClientType type,
base::UnguessableToken token,
RegisterClientWithTokenCallback callback);
void AddClientObserverOnProxyThread(
std::unique_ptr<CameraClientObserver> observer);
std::unique_ptr<CameraClientObserver> observer,
base::OnceCallback<void(int32_t)> result_callback);
void EstablishMojoChannel(CameraClientObserver* client_observer);
......@@ -131,6 +166,9 @@ class CAPTURE_EXPORT CameraHalDispatcherImpl final
mojo::Remote<cros::mojom::CameraHalServer> camera_hal_server_;
mojo::Receiver<cros::mojom::CameraHalServerCallbacks>
camera_hal_server_callbacks_;
std::set<std::unique_ptr<CameraClientObserver>, base::UniquePtrComparator>
client_observers_;
......@@ -138,6 +176,8 @@ class CAPTURE_EXPORT CameraHalDispatcherImpl final
MojoJpegEncodeAcceleratorFactoryCB jea_factory_;
TokenManager token_manager_;
DISALLOW_COPY_AND_ASSIGN(CameraHalDispatcherImpl);
};
......
......@@ -31,13 +31,15 @@ class MockCameraHalServer : public cros::mojom::CameraHalServer {
~MockCameraHalServer() = default;
void CreateChannel(mojo::PendingReceiver<cros::mojom::CameraModule>
camera_module_receiver) override {
DoCreateChannel(std::move(camera_module_receiver));
void CreateChannel(
mojo::PendingReceiver<cros::mojom::CameraModule> camera_module_receiver,
cros::mojom::CameraClientType camera_client_type) override {
DoCreateChannel(std::move(camera_module_receiver), camera_client_type);
}
MOCK_METHOD1(DoCreateChannel,
MOCK_METHOD2(DoCreateChannel,
void(mojo::PendingReceiver<cros::mojom::CameraModule>
camera_module_receiver));
camera_module_receiver,
cros::mojom::CameraClientType camera_client_type));
MOCK_METHOD1(SetTracingEnabled, void(bool enabled));
......@@ -106,12 +108,16 @@ class CameraHalDispatcherImplTest : public ::testing::Test {
static void RegisterServer(
CameraHalDispatcherImpl* dispatcher,
mojo::PendingRemote<cros::mojom::CameraHalServer> server) {
// TODO(b/170075468): Migrate to RegisterServerWithToken once the migration
// is done.
dispatcher->RegisterServer(std::move(server));
}
static void RegisterClient(
CameraHalDispatcherImpl* dispatcher,
mojo::PendingRemote<cros::mojom::CameraHalClient> client) {
// TODO(b/170075468): Migrate to RegisterClientWithToken once the migration
// is done.
dispatcher->RegisterClient(std::move(client));
}
......@@ -134,7 +140,7 @@ TEST_F(CameraHalDispatcherImplTest, ServerConnectionError) {
auto mock_server = std::make_unique<MockCameraHalServer>();
auto mock_client = std::make_unique<MockCameraHalClient>();
EXPECT_CALL(*mock_server, DoCreateChannel(_)).Times(1);
EXPECT_CALL(*mock_server, DoCreateChannel(_, _)).Times(1);
EXPECT_CALL(*mock_client, DoSetUpChannel(_))
.Times(1)
.WillOnce(
......@@ -159,7 +165,7 @@ TEST_F(CameraHalDispatcherImplTest, ServerConnectionError) {
// Make sure we creates a new Mojo channel from the new server to the same
// client.
EXPECT_CALL(*mock_server, DoCreateChannel(_)).Times(1);
EXPECT_CALL(*mock_server, DoCreateChannel(_, _)).Times(1);
EXPECT_CALL(*mock_client, DoSetUpChannel(_))
.Times(1)
.WillOnce(
......@@ -183,7 +189,7 @@ TEST_F(CameraHalDispatcherImplTest, ClientConnectionError) {
auto mock_server = std::make_unique<MockCameraHalServer>();
auto mock_client = std::make_unique<MockCameraHalClient>();
EXPECT_CALL(*mock_server, DoCreateChannel(_)).Times(1);
EXPECT_CALL(*mock_server, DoCreateChannel(_, _)).Times(1);
EXPECT_CALL(*mock_client, DoSetUpChannel(_))
.Times(1)
.WillOnce(
......@@ -208,7 +214,7 @@ TEST_F(CameraHalDispatcherImplTest, ClientConnectionError) {
// Make sure we re-create the Mojo channel from the same server to the new
// client.
EXPECT_CALL(*mock_server, DoCreateChannel(_)).Times(1);
EXPECT_CALL(*mock_server, DoCreateChannel(_, _)).Times(1);
EXPECT_CALL(*mock_client, DoSetUpChannel(_))
.Times(1)
.WillOnce(
......
......@@ -2,13 +2,24 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Next min version: 4
// Next min version: 5
module cros.mojom;
import "components/chromeos_camera/common/jpeg_encode_accelerator.mojom";
import "components/chromeos_camera/common/mjpeg_decode_accelerator.mojom";
import "media/capture/video/chromeos/mojom/camera_common.mojom";
import "mojo/public/mojom/base/unguessable_token.mojom";
// CameraClientType indicates the type of a CameraHalClient.
[Extensible]
enum CameraClientType{
UNKNOWN = 0,
TESTING = 1,
CHROME = 2,
ANDROID = 3,
PLUGINVM = 4,
};
// The CrOS camera HAL v3 Mojo dispatcher. The dispatcher acts as a proxy and
// waits for the server and the clients to register. There can only be one
......@@ -17,12 +28,14 @@ import "media/capture/video/chromeos/mojom/camera_common.mojom";
// channel to the server and pass the established Mojo channel to the client in
// order to set up a Mojo channel between the client and the server.
//
// Next method ID: 4
// Next method ID: 6
interface CameraHalDispatcher {
// [Deprecated in version 4]
// A CameraHalServer calls RegisterServer to register itself with the
// dispatcher.
RegisterServer@0(pending_remote<CameraHalServer> server);
// [Deprecated in version 4]
// A CameraHalClient calls RegisterClient to register itself with the
// dispatcher.
RegisterClient@1(pending_remote<CameraHalClient> client);
......@@ -35,6 +48,25 @@ interface CameraHalDispatcher {
// Get JpegEncodeAccelerator from dispatcher.
[MinVersion=2] GetJpegEncodeAccelerator@3(
pending_receiver<chromeos_camera.mojom.JpegEncodeAccelerator> jea_receiver);
// A CameraHalServer calls RegisterServerWithToken to register itself with the
// dispatcher. CameraHalDispatcher would authenticate the server with the
// supplied |auth_token|. |callbacks| is fired by CameraHalServer to notify
// CameraHalDispatcher about CameraHalClient updates, for example when a
// CameraHalClient opens or closes a camera device.
[MinVersion=4] RegisterServerWithToken@4(
pending_remote<CameraHalServer> server,
mojo_base.mojom.UnguessableToken auth_token) =>
(int32 result, pending_remote<CameraHalServerCallbacks> callbacks);
// A CameraHalClient calls RegisterClient to register itself with the
// dispatcher. CameraHalDispatcher would authenticate the client with the
// given |type| and |auth_token|.
[MinVersion=4] RegisterClientWithToken@5(
pending_remote<CameraHalClient> client,
CameraClientType type,
mojo_base.mojom.UnguessableToken auth_token) => (int32 result);
};
// The CrOS camera HAL v3 Mojo server.
......@@ -45,13 +77,28 @@ interface CameraHalServer {
// HAL v3 adapter. Upon successfully binding of |camera_module_request|, the
// caller will have a established Mojo channel to the camera HAL v3 adapter
// process.
CreateChannel@0(pending_receiver<CameraModule> camera_module_request);
CreateChannel@0(pending_receiver<CameraModule> camera_module_request,
[MinVersion=4] CameraClientType type);
// Enable or disable tracing.
[MinVersion=3]
SetTracingEnabled@1(bool enabled);
};
// CameraHalServerCallbacks is an interface for CameraHalServer to notify
// CameraHalDispatcher for any changes on the server side, for example when a
// CameraHalClient opens or closes a camera device.
//
// Next method ID: 1
interface CameraHalServerCallbacks {
// Fired when a CameraHalClient opens or closes a camera device. When a
// CameraHalClient loses mojo connection to CameraHalServer, CameraHalServer
// would also use this to notify that cameras are closed (not being used).
CameraDeviceActivityChange@0(int32 camera_id,
bool opened,
CameraClientType type);
};
// The CrOS camera HAL v3 Mojo client.
//
// Next method ID: 1
......
// 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 "media/capture/video/chromeos/token_manager.h"
namespace media {
TokenManager::TokenManager() = default;
TokenManager::~TokenManager() = default;
base::UnguessableToken TokenManager::GetTokenForTrustedClient(
cros::mojom::CameraClientType type) {
// pluginvm's token should be generated by vm_permission_service.
CHECK_NE(type, cros::mojom::CameraClientType::PLUGINVM);
auto& token = client_token_map_[type];
if (token.is_empty()) {
token = base::UnguessableToken::Create();
}
return token;
}
bool TokenManager::AuthenticateClient(cros::mojom::CameraClientType type,
const base::UnguessableToken& token) {
// TODO(b/170075468): Check other clients after they have been migrated to
// CameraHalDispatcher::RegisterClientWithToken.
if (type != cros::mojom::CameraClientType::CHROME) {
return true;
}
auto it = client_token_map_.find(type);
return it != client_token_map_.end() && it->second == token;
}
} // namespace media
// 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 MEDIA_CAPTURE_VIDEO_CHROMEOS_TOKEN_MANAGER_H_
#define MEDIA_CAPTURE_VIDEO_CHROMEOS_TOKEN_MANAGER_H_
#include "base/containers/flat_map.h"
#include "base/unguessable_token.h"
#include "media/capture/video/chromeos/mojom/cros_camera_service.mojom.h"
namespace media {
class TokenManager {
public:
TokenManager();
~TokenManager();
base::UnguessableToken GetTokenForTrustedClient(
cros::mojom::CameraClientType type);
bool AuthenticateClient(cros::mojom::CameraClientType type,
const base::UnguessableToken& token);
private:
base::flat_map<cros::mojom::CameraClientType, base::UnguessableToken>
client_token_map_;
};
} // namespace media
#endif // MEDIA_CAPTURE_VIDEO_CHROMEOS_TOKEN_MANAGER_H_
......@@ -83,7 +83,10 @@ bool VideoCaptureDeviceFactoryChromeOS::Init() {
camera_hal_delegate_ =
new CameraHalDelegate(camera_hal_ipc_thread_.task_runner());
camera_hal_delegate_->RegisterCameraClient();
if (!camera_hal_delegate_->RegisterCameraClient()) {
LOG(ERROR) << "Failed to register camera client";
return false;
}
// Since the |camera_hal_delegate_| is initialized on the constructor of this
// object and is destroyed after |camera_app_device_bridge_| unsetting its
......
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