Commit e839ee5a authored by Wei Lee's avatar Wei Lee Committed by Chromium LUCI CQ

VCD: Add CameraPrivacySwitchObserver

This CL implements the CameraPrivacySwitchObserver on Chrome side and
provide an interface in CameraHalDispatcherImpl to let other components
in Chrome to add observers for camera privacy switch status changed.

Bug: b/167994459
Test: Build successfully
Change-Id: I4efe132cd2d0a5988a4ffeb99ab0ca2802ad2a63
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2551882
Commit-Queue: Wei Lee <wtlee@chromium.org>
Reviewed-by: default avatarRobert Sesek <rsesek@chromium.org>
Reviewed-by: default avatarShik Chen <shik@chromium.org>
Cr-Commit-Position: refs/heads/master@{#836521}
parent 5d7e47f4
...@@ -115,6 +115,9 @@ void FailedCameraHalServerCallbacks::CameraDeviceActivityChange( ...@@ -115,6 +115,9 @@ void FailedCameraHalServerCallbacks::CameraDeviceActivityChange(
bool opened, bool opened,
cros::mojom::CameraClientType type) {} cros::mojom::CameraClientType type) {}
void FailedCameraHalServerCallbacks::CameraPrivacySwitchStateChange(
cros::mojom::CameraPrivacySwitchState state) {}
// static // static
CameraHalDispatcherImpl* CameraHalDispatcherImpl::GetInstance() { CameraHalDispatcherImpl* CameraHalDispatcherImpl::GetInstance() {
return base::Singleton<CameraHalDispatcherImpl>::get(); return base::Singleton<CameraHalDispatcherImpl>::get();
...@@ -208,6 +211,20 @@ void CameraHalDispatcherImpl::RemoveActiveClientObserver( ...@@ -208,6 +211,20 @@ void CameraHalDispatcherImpl::RemoveActiveClientObserver(
active_client_observers_->RemoveObserver(observer); active_client_observers_->RemoveObserver(observer);
} }
cros::mojom::CameraPrivacySwitchState
CameraHalDispatcherImpl::AddCameraPrivacySwitchObserver(
CameraPrivacySwitchObserver* observer) {
privacy_switch_observers_->AddObserver(observer);
base::AutoLock lock(privacy_switch_state_lock_);
return current_privacy_switch_state_;
}
void CameraHalDispatcherImpl::RemoveCameraPrivacySwitchObserver(
CameraPrivacySwitchObserver* observer) {
privacy_switch_observers_->RemoveObserver(observer);
}
void CameraHalDispatcherImpl::RegisterPluginVmToken( void CameraHalDispatcherImpl::RegisterPluginVmToken(
const base::UnguessableToken& token) { const base::UnguessableToken& token) {
token_manager_.RegisterPluginVmToken(token); token_manager_.RegisterPluginVmToken(token);
...@@ -223,7 +240,11 @@ CameraHalDispatcherImpl::CameraHalDispatcherImpl() ...@@ -223,7 +240,11 @@ CameraHalDispatcherImpl::CameraHalDispatcherImpl()
blocking_io_thread_("CameraBlockingIOThread"), blocking_io_thread_("CameraBlockingIOThread"),
camera_hal_server_callbacks_(this), camera_hal_server_callbacks_(this),
active_client_observers_( active_client_observers_(
new base::ObserverListThreadSafe<CameraActiveClientObserver>()) {} new base::ObserverListThreadSafe<CameraActiveClientObserver>()),
current_privacy_switch_state_(
cros::mojom::CameraPrivacySwitchState::UNKNOWN),
privacy_switch_observers_(
new base::ObserverListThreadSafe<CameraPrivacySwitchObserver>()) {}
CameraHalDispatcherImpl::~CameraHalDispatcherImpl() { CameraHalDispatcherImpl::~CameraHalDispatcherImpl() {
VLOG(1) << "Stopping CameraHalDispatcherImpl..."; VLOG(1) << "Stopping CameraHalDispatcherImpl...";
...@@ -359,6 +380,18 @@ void CameraHalDispatcherImpl::CameraDeviceActivityChange( ...@@ -359,6 +380,18 @@ void CameraHalDispatcherImpl::CameraDeviceActivityChange(
} }
} }
void CameraHalDispatcherImpl::CameraPrivacySwitchStateChange(
cros::mojom::CameraPrivacySwitchState state) {
DCHECK(proxy_task_runner_->BelongsToCurrentThread());
base::AutoLock lock(privacy_switch_state_lock_);
current_privacy_switch_state_ = state;
privacy_switch_observers_->Notify(
FROM_HERE,
&CameraPrivacySwitchObserver::OnCameraPrivacySwitchStatusChanged,
current_privacy_switch_state_);
}
base::UnguessableToken CameraHalDispatcherImpl::GetTokenForTrustedClient( base::UnguessableToken CameraHalDispatcherImpl::GetTokenForTrustedClient(
cros::mojom::CameraClientType type) { cros::mojom::CameraClientType type) {
return token_manager_.GetTokenForTrustedClient(type); return token_manager_.GetTokenForTrustedClient(type);
...@@ -568,6 +601,14 @@ void CameraHalDispatcherImpl::OnCameraHalServerConnectionError() { ...@@ -568,6 +601,14 @@ void CameraHalDispatcherImpl::OnCameraHalServerConnectionError() {
} }
} }
opened_camera_id_map_.clear(); opened_camera_id_map_.clear();
base::AutoLock privacy_lock(privacy_switch_state_lock_);
current_privacy_switch_state_ =
cros::mojom::CameraPrivacySwitchState::UNKNOWN;
privacy_switch_observers_->Notify(
FROM_HERE,
&CameraPrivacySwitchObserver::OnCameraPrivacySwitchStatusChanged,
current_privacy_switch_state_);
} }
void CameraHalDispatcherImpl::OnCameraHalClientConnectionError( void CameraHalDispatcherImpl::OnCameraHalClientConnectionError(
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include "base/memory/singleton.h" #include "base/memory/singleton.h"
#include "base/observer_list_threadsafe.h" #include "base/observer_list_threadsafe.h"
#include "base/observer_list_types.h" #include "base/observer_list_types.h"
#include "base/synchronization/lock.h"
#include "base/synchronization/waitable_event.h" #include "base/synchronization/waitable_event.h"
#include "base/thread_annotations.h" #include "base/thread_annotations.h"
#include "base/threading/thread.h" #include "base/threading/thread.h"
...@@ -90,10 +91,22 @@ class FailedCameraHalServerCallbacks ...@@ -90,10 +91,22 @@ class FailedCameraHalServerCallbacks
void CameraDeviceActivityChange(int32_t camera_id, void CameraDeviceActivityChange(int32_t camera_id,
bool opened, bool opened,
cros::mojom::CameraClientType type) final; cros::mojom::CameraClientType type) final;
void CameraPrivacySwitchStateChange(
cros::mojom::CameraPrivacySwitchState state) final;
mojo::Receiver<cros::mojom::CameraHalServerCallbacks> callbacks_; mojo::Receiver<cros::mojom::CameraHalServerCallbacks> callbacks_;
}; };
class CAPTURE_EXPORT CameraPrivacySwitchObserver
: public base::CheckedObserver {
public:
virtual void OnCameraPrivacySwitchStatusChanged(
cros::mojom::CameraPrivacySwitchState state) = 0;
protected:
~CameraPrivacySwitchObserver() override = default;
};
// The CameraHalDispatcherImpl hosts and waits on the unix domain socket // The CameraHalDispatcherImpl hosts and waits on the unix domain socket
// /var/run/camera3.sock. CameraHalServer and CameraHalClients connect to the // /var/run/camera3.sock. CameraHalServer and CameraHalClients connect to the
// unix domain socket to create the initial Mojo connections with the // unix domain socket to create the initial Mojo connections with the
...@@ -127,6 +140,17 @@ class CAPTURE_EXPORT CameraHalDispatcherImpl final ...@@ -127,6 +140,17 @@ class CAPTURE_EXPORT CameraHalDispatcherImpl final
// being destroyed. // being destroyed.
void RemoveActiveClientObserver(CameraActiveClientObserver* observer); void RemoveActiveClientObserver(CameraActiveClientObserver* observer);
// Adds an observer to get notified when the camera privacy switch status
// changed. Please note that for some devices, the signal will only be
// detectable when the camera is currently on due to hardware limitations.
// Returns the current state of the camera privacy switch.
cros::mojom::CameraPrivacySwitchState AddCameraPrivacySwitchObserver(
CameraPrivacySwitchObserver* observer);
// Removes the observer. A previously-added observer must be removed before
// being destroyed.
void RemoveCameraPrivacySwitchObserver(CameraPrivacySwitchObserver* observer);
// Called by vm_permission_service to register the token used for pluginvm. // Called by vm_permission_service to register the token used for pluginvm.
void RegisterPluginVmToken(const base::UnguessableToken& token); void RegisterPluginVmToken(const base::UnguessableToken& token);
void UnregisterPluginVmToken(const base::UnguessableToken& token); void UnregisterPluginVmToken(const base::UnguessableToken& token);
...@@ -156,6 +180,8 @@ class CAPTURE_EXPORT CameraHalDispatcherImpl final ...@@ -156,6 +180,8 @@ class CAPTURE_EXPORT CameraHalDispatcherImpl final
void CameraDeviceActivityChange(int32_t camera_id, void CameraDeviceActivityChange(int32_t camera_id,
bool opened, bool opened,
cros::mojom::CameraClientType type) final; cros::mojom::CameraClientType type) final;
void CameraPrivacySwitchStateChange(
cros::mojom::CameraPrivacySwitchState state) final;
base::UnguessableToken GetTokenForTrustedClient( base::UnguessableToken GetTokenForTrustedClient(
cros::mojom::CameraClientType type); cros::mojom::CameraClientType type);
...@@ -240,6 +266,13 @@ class CAPTURE_EXPORT CameraHalDispatcherImpl final ...@@ -240,6 +266,13 @@ class CAPTURE_EXPORT CameraHalDispatcherImpl final
scoped_refptr<base::ObserverListThreadSafe<CameraActiveClientObserver>> scoped_refptr<base::ObserverListThreadSafe<CameraActiveClientObserver>>
active_client_observers_; active_client_observers_;
base::Lock privacy_switch_state_lock_;
cros::mojom::CameraPrivacySwitchState current_privacy_switch_state_
GUARDED_BY(privacy_switch_state_lock_);
scoped_refptr<base::ObserverListThreadSafe<CameraPrivacySwitchObserver>>
privacy_switch_observers_;
DISALLOW_COPY_AND_ASSIGN(CameraHalDispatcherImpl); DISALLOW_COPY_AND_ASSIGN(CameraHalDispatcherImpl);
}; };
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// Next min version: 5 // Next min version: 6
module cros.mojom; module cros.mojom;
...@@ -21,6 +21,22 @@ enum CameraClientType{ ...@@ -21,6 +21,22 @@ enum CameraClientType{
PLUGINVM = 4, PLUGINVM = 4,
}; };
// CameraPrivacySwitchState indicates the state of the camera privacy switch.
enum CameraPrivacySwitchState{
// For devices which can only read the privacy switch status while the camera
// is streaming, it is possible that the state of privacy switch is currently
// unknown.
UNKNOWN = 0,
// State when the privacy switch is on, which means the black frames will be
// delivered when streaming.
ON = 1,
// State when the privacy switch is off, which means camera should stream
// normally.
OFF = 2,
};
// The CrOS camera HAL v3 Mojo dispatcher. The dispatcher acts as a proxy and // 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 // waits for the server and the clients to register. There can only be one
// server registered, with multiple clients requesting connections to the // server registered, with multiple clients requesting connections to the
...@@ -89,7 +105,7 @@ interface CameraHalServer { ...@@ -89,7 +105,7 @@ interface CameraHalServer {
// CameraHalDispatcher for any changes on the server side, for example when a // CameraHalDispatcher for any changes on the server side, for example when a
// CameraHalClient opens or closes a camera device. // CameraHalClient opens or closes a camera device.
// //
// Next method ID: 1 // Next method ID: 2
interface CameraHalServerCallbacks { interface CameraHalServerCallbacks {
// Fired when a CameraHalClient opens or closes a camera device. When a // Fired when a CameraHalClient opens or closes a camera device. When a
// CameraHalClient loses mojo connection to CameraHalServer, CameraHalServer // CameraHalClient loses mojo connection to CameraHalServer, CameraHalServer
...@@ -97,6 +113,12 @@ interface CameraHalServerCallbacks { ...@@ -97,6 +113,12 @@ interface CameraHalServerCallbacks {
CameraDeviceActivityChange@0(int32 camera_id, CameraDeviceActivityChange@0(int32 camera_id,
bool opened, bool opened,
CameraClientType type); CameraClientType type);
// Fired when the camera privacy switch status is changed. If the device has
// such switch, this callback will be fired immediately for once to notify its
// current status when the callbacks are registered.
[MinVersion=5]
CameraPrivacySwitchStateChange@1(CameraPrivacySwitchState state);
}; };
// The CrOS camera HAL v3 Mojo client. // The CrOS camera HAL v3 Mojo client.
......
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