Skip to content

Commit

Permalink
camera: check if autozoom is supported by camera HAL
Browse files Browse the repository at this point in the history
Check if autozoom is supported by camera HAL, and only shows the feature
pod button, toast and educational nudge if it's supported.

This needs platform side support (CL:3817780) to works.

Bug: b:221980963
Test: manually
Test: ash_unittests --gtest_filter="AutozoomToastControllerTest*"
Test: capture_unittests --gtest_filter="CameraHalDispatcherImplTest.*"
Change-Id: I6ae8b1142616b7c55fc8e06c7b312f50985114da
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3812481
Auto-Submit: Pi-Hsun Shih <pihsun@chromium.org>
Reviewed-by: Shik Chen <shik@chromium.org>
Reviewed-by: Daniel Cheng <dcheng@chromium.org>
Commit-Queue: Daniel Cheng <dcheng@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1034766}
  • Loading branch information
peter50216 authored and Chromium LUCI CQ committed Aug 13, 2022
1 parent 4b4ef11 commit 2f3c620
Show file tree
Hide file tree
Showing 14 changed files with 166 additions and 118 deletions.
50 changes: 49 additions & 1 deletion ash/system/camera/autozoom_controller_impl.cc
Expand Up @@ -7,18 +7,34 @@
#include "ash/constants/ash_pref_names.h"
#include "ash/session/session_controller_impl.h"
#include "ash/shell.h"
#include "base/logging.h"
#include "media/capture/video/chromeos/camera_hal_dispatcher_impl.h"

namespace ash {

AutozoomControllerImpl::AutozoomControllerImpl()
: nudge_controller_(std::make_unique<AutozoomNudgeController>(this)) {
auto* camera_hal_dispatcher = media::CameraHalDispatcherImpl::GetInstance();
if (camera_hal_dispatcher) {
camera_hal_dispatcher->GetAutoFramingSupported(
base::BindOnce(&AutozoomControllerImpl::SetAutozoomSupported,
weak_ptr_factory_.GetWeakPtr()));
camera_hal_dispatcher->AddActiveClientObserver(this);
}

Shell::Get()->session_controller()->AddObserver(this);
}

AutozoomControllerImpl::~AutozoomControllerImpl() {
Shell::Get()->session_controller()->RemoveObserver(this);

auto* camera_hal_dispatcher = media::CameraHalDispatcherImpl::GetInstance();
if (camera_hal_dispatcher) {
camera_hal_dispatcher->RemoveActiveClientObserver(this);
}
}

bool AutozoomControllerImpl::IsAutozoomControlEnabled() {
return autozoom_supported_ && active_camera_client_count_ > 0;
}

cros::mojom::CameraAutoFramingState AutozoomControllerImpl::GetState() {
Expand All @@ -33,6 +49,19 @@ void AutozoomControllerImpl::SetState(
}
}

void AutozoomControllerImpl::SetAutozoomSupported(bool autozoom_supported) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

bool orig_control_enabled = IsAutozoomControlEnabled();
autozoom_supported_ = autozoom_supported;

bool control_enabled = IsAutozoomControlEnabled();
if (control_enabled != orig_control_enabled) {
for (auto& observer : observers_)
observer.OnAutozoomControlEnabledChanged(control_enabled);
}
}

void AutozoomControllerImpl::Toggle() {
SetState(state_ == cros::mojom::CameraAutoFramingState::OFF
? cros::mojom::CameraAutoFramingState::ON_SINGLE
Expand Down Expand Up @@ -62,6 +91,7 @@ void AutozoomControllerImpl::OnStatePrefChanged() {
}

void AutozoomControllerImpl::Refresh() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (active_user_pref_service_) {
state_ = static_cast<cros::mojom::CameraAutoFramingState>(
active_user_pref_service_->GetInteger(prefs::kAutozoomState));
Expand Down Expand Up @@ -94,6 +124,24 @@ void AutozoomControllerImpl::InitFromUserPrefs() {
Refresh();
}

void AutozoomControllerImpl::OnActiveClientChange(
cros::mojom::CameraClientType type,
bool is_active) {
bool orig_control_enabled = IsAutozoomControlEnabled();
if (is_active) {
active_camera_client_count_++;
} else {
DCHECK(active_camera_client_count_ > 0);
active_camera_client_count_--;
}

bool control_enabled = IsAutozoomControlEnabled();
if (control_enabled != orig_control_enabled) {
for (auto& observer : observers_)
observer.OnAutozoomControlEnabledChanged(control_enabled);
}
}

// static
void AutozoomControllerImpl::RegisterProfilePrefs(
PrefRegistrySimple* registry) {
Expand Down
24 changes: 23 additions & 1 deletion ash/system/camera/autozoom_controller_impl.h
Expand Up @@ -14,14 +14,17 @@
#include "components/prefs/pref_change_registrar.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/pref_service.h"
#include "media/capture/video/chromeos/camera_hal_dispatcher_impl.h"
#include "media/capture/video/chromeos/mojom/cros_camera_service.mojom.h"

namespace ash {

// Controls the Autozoom feature that, when enabled, intelligently
// pans/tilts/zooms the camera to frame a set of regions of interest captured
// by the camera.
class ASH_EXPORT AutozoomControllerImpl : public SessionObserver {
class ASH_EXPORT AutozoomControllerImpl
: public SessionObserver,
public media::CameraActiveClientObserver {
public:
AutozoomControllerImpl();

Expand All @@ -41,6 +44,8 @@ class ASH_EXPORT AutozoomControllerImpl : public SessionObserver {
void AddObserver(AutozoomObserver* observer);
void RemoveObserver(AutozoomObserver* observer);

bool IsAutozoomControlEnabled();

// SessionObserver:
void OnActiveUserPrefServiceChanged(PrefService* pref_service) override;

Expand All @@ -54,6 +59,12 @@ class ASH_EXPORT AutozoomControllerImpl : public SessionObserver {
// Called when the user pref for the enabled status of Autozoom is changed.
void OnStatePrefChanged();

void SetAutozoomSupported(bool autozoom_supported);

// CameraActiveClientObserver
void OnActiveClientChange(cros::mojom::CameraClientType type,
bool is_active) override;

// The pref service of the currently active user. Can be null in
// ash_unittests.
PrefService* active_user_pref_service_ = nullptr;
Expand All @@ -69,6 +80,17 @@ class ASH_EXPORT AutozoomControllerImpl : public SessionObserver {
base::ObserverList<AutozoomObserver> observers_;

std::unique_ptr<AutozoomNudgeController> nudge_controller_;

bool autozoom_supported_ = false;

// The number of current active camera clients. Autozoom control should only
// be shown when there's at least one active camera client.
int active_camera_client_count_ = 0;

// All methods of this class should be run on the same sequence.
SEQUENCE_CHECKER(sequence_checker_);

base::WeakPtrFactory<AutozoomControllerImpl> weak_ptr_factory_{this};
};

} // namespace ash
Expand Down
31 changes: 7 additions & 24 deletions ash/system/camera/autozoom_feature_pod_controller.cc
Expand Up @@ -16,21 +16,11 @@
namespace ash {

AutozoomFeaturePodController::AutozoomFeaturePodController() {
auto* camera_hal_dispatcher = media::CameraHalDispatcherImpl::GetInstance();
if (camera_hal_dispatcher) {
camera_hal_dispatcher->AddActiveClientObserver(this);
}

Shell::Get()->autozoom_controller()->AddObserver(this);
}

AutozoomFeaturePodController::~AutozoomFeaturePodController() {
Shell::Get()->autozoom_controller()->RemoveObserver(this);

auto* camera_hal_dispatcher = media::CameraHalDispatcherImpl::GetInstance();
if (camera_hal_dispatcher) {
camera_hal_dispatcher->RemoveActiveClientObserver(this);
}
}

FeaturePodButton* AutozoomFeaturePodController::CreateButton() {
Expand Down Expand Up @@ -67,15 +57,20 @@ void AutozoomFeaturePodController::UpdateButtonVisibility() {
return;

button_->SetVisible(
Shell::Get()->session_controller()->ShouldEnableSettings() &&
active_camera_client_count_ > 0);
Shell::Get()->autozoom_controller()->IsAutozoomControlEnabled() &&
Shell::Get()->session_controller()->ShouldEnableSettings());
}

void AutozoomFeaturePodController::OnAutozoomStateChanged(
cros::mojom::CameraAutoFramingState state) {
UpdateButton(state);
}

void AutozoomFeaturePodController::OnAutozoomControlEnabledChanged(
bool enabled) {
UpdateButtonVisibility();
}

void AutozoomFeaturePodController::UpdateButton(
cros::mojom::CameraAutoFramingState state) {
if (!button_)
Expand Down Expand Up @@ -108,16 +103,4 @@ void AutozoomFeaturePodController::UpdateButton(
IDS_ASH_STATUS_TRAY_AUTOZOOM_TOGGLE_TOOLTIP, tooltip_state));
}

void AutozoomFeaturePodController::OnActiveClientChange(
cros::mojom::CameraClientType type,
bool is_active) {
if (is_active) {
active_camera_client_count_++;
} else {
active_camera_client_count_--;
}

UpdateButtonVisibility();
}

} // namespace ash
9 changes: 1 addition & 8 deletions ash/system/camera/autozoom_feature_pod_controller.h
Expand Up @@ -7,13 +7,11 @@

#include "ash/system/camera/autozoom_observer.h"
#include "ash/system/unified/feature_pod_controller_base.h"
#include "media/capture/video/chromeos/camera_hal_dispatcher_impl.h"

namespace ash {

// Controller of a feature pod button that toggles autozoom.
class AutozoomFeaturePodController : public FeaturePodControllerBase,
public media::CameraActiveClientObserver,
public AutozoomObserver {
public:
AutozoomFeaturePodController();
Expand All @@ -33,19 +31,14 @@ class AutozoomFeaturePodController : public FeaturePodControllerBase,
// AutozoomObserver:
void OnAutozoomStateChanged(
cros::mojom::CameraAutoFramingState state) override;
void OnAutozoomControlEnabledChanged(bool enabled) override;

private:
void UpdateButton(cros::mojom::CameraAutoFramingState state);

void UpdateButtonVisibility();

// CameraActiveClientObserver
void OnActiveClientChange(cros::mojom::CameraClientType type,
bool is_active) override;

FeaturePodButton* button_ = nullptr;

int active_camera_client_count_ = 0;
};

} // namespace ash
Expand Down
14 changes: 2 additions & 12 deletions ash/system/camera/autozoom_nudge_controller.cc
Expand Up @@ -30,21 +30,13 @@ AutozoomNudgeController::AutozoomNudgeController(
: autozoom_controller_(autozoom_controller) {
autozoom_controller_->AddObserver(this);

auto* camera_hal_dispatcher = media::CameraHalDispatcherImpl::GetInstance();
if (camera_hal_dispatcher)
camera_hal_dispatcher->AddActiveClientObserver(this);

if (base::FeatureList::IsEnabled(features::kAutozoomNudgeSessionReset))
Shell::Get()->session_controller()->AddObserver(this);
}

AutozoomNudgeController::~AutozoomNudgeController() {
autozoom_controller_->RemoveObserver(this);

auto* camera_hal_dispatcher = media::CameraHalDispatcherImpl::GetInstance();
if (camera_hal_dispatcher)
camera_hal_dispatcher->RemoveActiveClientObserver(this);

if (base::FeatureList::IsEnabled(features::kAutozoomNudgeSessionReset))
Shell::Get()->session_controller()->RemoveObserver(this);
}
Expand Down Expand Up @@ -128,10 +120,8 @@ bool AutozoomNudgeController::ShouldShowNudge(PrefService* prefs) {
return (base::Time::Now() - last_shown_time) > kMinInterval;
}

void AutozoomNudgeController::OnActiveClientChange(
cros::mojom::CameraClientType type,
bool is_active) {
if (!is_active)
void AutozoomNudgeController::OnAutozoomControlEnabledChanged(bool enabled) {
if (!enabled)
return;

PrefService* prefs =
Expand Down
14 changes: 4 additions & 10 deletions ash/system/camera/autozoom_nudge_controller.h
Expand Up @@ -10,7 +10,6 @@
#include "ash/system/camera/autozoom_observer.h"
#include "ash/system/tray/system_nudge_controller.h"
#include "base/time/time.h"
#include "media/capture/video/chromeos/camera_hal_dispatcher_impl.h"

class PrefService;
class PrefRegistrySimple;
Expand All @@ -19,11 +18,9 @@ namespace ash {

class AutozoomControllerImpl;

class ASH_EXPORT AutozoomNudgeController
: public SystemNudgeController,
public AutozoomObserver,
public SessionObserver,
public media::CameraActiveClientObserver {
class ASH_EXPORT AutozoomNudgeController : public SystemNudgeController,
public AutozoomObserver,
public SessionObserver {
public:
explicit AutozoomNudgeController(AutozoomControllerImpl* controller);
AutozoomNudgeController(const AutozoomNudgeController&) = delete;
Expand Down Expand Up @@ -57,10 +54,7 @@ class ASH_EXPORT AutozoomNudgeController
// AutozoomObserver:
void OnAutozoomStateChanged(
cros::mojom::CameraAutoFramingState state) override;

// CameraActiveClientObserver:
void OnActiveClientChange(cros::mojom::CameraClientType type,
bool is_active) override;
void OnAutozoomControlEnabledChanged(bool enabled) override;

// Owned by ash/Shell.
AutozoomControllerImpl* const autozoom_controller_;
Expand Down
3 changes: 3 additions & 0 deletions ash/system/camera/autozoom_observer.h
Expand Up @@ -15,6 +15,9 @@ class AutozoomObserver : public base::CheckedObserver {
// Called when the autozoom state has changed.
virtual void OnAutozoomStateChanged(
cros::mojom::CameraAutoFramingState state) {}

// Called when the autozoom control enabled state has changed.
virtual void OnAutozoomControlEnabledChanged(bool enabled) {}
};

} // namespace ash
Expand Down
35 changes: 9 additions & 26 deletions ash/system/camera/autozoom_toast_controller.cc
Expand Up @@ -27,39 +27,25 @@ void AutozoomToastController::Delegate::RemoveAutozoomObserver(
Shell::Get()->autozoom_controller()->RemoveObserver(observer);
}

void AutozoomToastController::Delegate::AddCameraActiveClientObserver(
media::CameraActiveClientObserver* observer) {
auto* camera_hal_dispatcher = media::CameraHalDispatcherImpl::GetInstance();
if (camera_hal_dispatcher) {
camera_hal_dispatcher->AddActiveClientObserver(observer);
}
}

void AutozoomToastController::Delegate::RemoveCameraActiveClientObserver(
media::CameraActiveClientObserver* observer) {
auto* camera_hal_dispatcher = media::CameraHalDispatcherImpl::GetInstance();
if (camera_hal_dispatcher) {
camera_hal_dispatcher->RemoveActiveClientObserver(observer);
}
}

bool AutozoomToastController::Delegate::AutozoomEnabled() {
bool AutozoomToastController::Delegate::IsAutozoomEnabled() {
return Shell::Get()->autozoom_controller()->GetState() !=
cros::mojom::CameraAutoFramingState::OFF;
}

bool AutozoomToastController::Delegate::IsAutozoomControlEnabled() {
return Shell::Get()->autozoom_controller()->IsAutozoomControlEnabled();
}

AutozoomToastController::AutozoomToastController(
UnifiedSystemTray* tray,
std::unique_ptr<Delegate> delegate)
: tray_(tray), delegate_(std::move(delegate)) {
delegate_->AddAutozoomObserver(this);
delegate_->AddCameraActiveClientObserver(this);
}

AutozoomToastController::~AutozoomToastController() {
if (bubble_widget_ && !bubble_widget_->IsClosed())
bubble_widget_->CloseNow();
delegate_->RemoveCameraActiveClientObserver(this);
delegate_->RemoveAutozoomObserver(this);
}

Expand Down Expand Up @@ -164,7 +150,7 @@ void AutozoomToastController::OnAutozoomStateChanged(

void AutozoomToastController::UpdateToastView() {
if (toast_view_) {
toast_view_->SetAutozoomEnabled(/*enabled=*/delegate_->AutozoomEnabled());
toast_view_->SetAutozoomEnabled(/*enabled=*/delegate_->IsAutozoomEnabled());
int width = base::clamp(toast_view_->GetPreferredSize().width(),
kAutozoomToastMinWidth, kAutozoomToastMaxWidth);
bubble_view_->SetPreferredWidth(width);
Expand All @@ -175,12 +161,9 @@ void AutozoomToastController::StopAutocloseTimer() {
close_timer_.Stop();
}

void AutozoomToastController::OnActiveClientChange(
cros::mojom::CameraClientType type,
bool is_active) {
// TODO(pihsun): Should this only be shown for some client type?
if (is_active) {
if (delegate_->AutozoomEnabled()) {
void AutozoomToastController::OnAutozoomControlEnabledChanged(bool enabled) {
if (enabled) {
if (delegate_->IsAutozoomEnabled()) {
ShowToast();
} else {
HideToast();
Expand Down

0 comments on commit 2f3c620

Please sign in to comment.