1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301
|
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef ASH_SYSTEM_CAMERA_CAMERA_EFFECTS_CONTROLLER_H_
#define ASH_SYSTEM_CAMERA_CAMERA_EFFECTS_CONTROLLER_H_
#include <string>
#include <utility>
#include "ash/ash_export.h"
#include "ash/public/cpp/session/session_controller.h"
#include "ash/public/cpp/session/session_observer.h"
#include "ash/public/cpp/wallpaper/sea_pen_image.h"
#include "ash/system/camera/autozoom_observer.h"
#include "ash/system/video_conference/effects/video_conference_tray_effects_delegate.h"
#include "ash/system/video_conference/video_conference_tray_controller.h"
#include "base/files/file_path.h"
#include "base/memory/weak_ptr.h"
#include "base/scoped_observation.h"
#include "media/capture/video/chromeos/camera_hal_dispatcher_impl.h"
#include "media/capture/video/chromeos/mojom/effects_pipeline.mojom.h"
class PrefRegistrySimple;
class PrefService;
class PrefChangeRegistrar;
namespace gfx {
struct VectorIcon;
} // namespace gfx
namespace ash {
enum class VcEffectId;
// CameraEffectsController is the interface for any object in ash to
// enable/change camera effects.
class ASH_EXPORT CameraEffectsController
: public AutozoomObserver,
public media::CameraEffectObserver,
public SessionObserver,
public VcEffectsDelegate,
public VideoConferenceTrayEffectsManager::Observer {
public:
// Enum that represents the value persisted to `prefs::kBackgroundBlur`,
// which is the "ultimate source of truth" for the background blur setting.
// WARNING: This enum and `prefs::kBackgroundBlur` should always be in sync.
// Any changes made to this enum or `prefs::kBackgroundBlur` should also be
// reflected in the other place.
enum BackgroundBlurPrefValue {
kOff = -1,
kLowest = 0,
kLight = 1,
kMedium = 2,
kHeavy = 3,
kMaximum = 4,
kImage = 5
};
// This enum contains all the state of the background blur effect. This enum
// is used for metrics collection (we cannot use `BackgroundBlurPrefValue`
// since `base::UmaHistogramEnumeration` cannot take a negative value for
// an enum). Note to keep in sync with enum in
// tools/metrics/histograms/metadata/ash/enums.xml.
enum class BackgroundBlurState {
kOff = 0,
kLowest = 1,
kLight = 2,
kMedium = 3,
kHeavy = 4,
kMaximum = 5,
kImage = 6,
kMaxValue = kImage
};
// Information of a single background image file used in the ui.
struct BackgroundImageInfo {
base::Time creation_time;
base::Time last_accessed;
base::FilePath basename;
gfx::ImageSkia image;
std::string metadata;
BackgroundImageInfo(const BackgroundImageInfo& info);
BackgroundImageInfo(const base::Time& creation_time,
const base::Time& last_accessed,
const base::FilePath& basename,
const gfx::ImageSkia& image,
const std::string& metadata);
};
// Called inside ash/ash_prefs.cc to register related prefs.
static void RegisterProfilePrefs(PrefRegistrySimple* registry);
static base::FilePath SeaPenIdToRelativePath(uint32_t id);
CameraEffectsController();
CameraEffectsController(const CameraEffectsController&) = delete;
CameraEffectsController& operator=(const CameraEffectsController&) = delete;
~CameraEffectsController() override;
// Returns 'true' if UI controls for `effect` are available to the user,
// 'false' otherwise.
bool IsEffectControlAvailable(
cros::mojom::CameraEffect effect = cros::mojom::CameraEffect::kNone);
// Returns currently applied camera effects.
// Should only be called after user logs in.
cros::mojom::EffectsConfigPtr GetCameraEffects();
// Sets an image as the camera background.
// The `relative_path` is relative to `camera_background_img_dir_` and the
// file has to exist for the effect to work.
void SetBackgroundImage(const base::FilePath& relative_path,
base::OnceCallback<void(bool)> callback);
// Saves the `jpeg_bytes` as an image file with `metadata` and apply that as
// camera background.
void SetBackgroundImageFromContent(const SeaPenImage& sea_pen_image,
const std::string& metadata,
base::OnceCallback<void(bool)> callback);
// Removes `basename` from the camera background directory; remove background
// effect if the same file is used as camera background right now.
void RemoveBackgroundImage(const base::FilePath& basename,
base::OnceCallback<void(bool)> callback);
// Gets `number_of_images` recently used camera background images, and calls
// the `callback` on the returned list.
void GetRecentlyUsedBackgroundImages(
const int number_of_images,
base::OnceCallback<void(const std::vector<BackgroundImageInfo>&)>
callback);
// Gets the full list of used background image paths and calls `callback` on
// that.
void GetBackgroundImageFileNames(
base::OnceCallback<void(const std::vector<base::FilePath>&)> callback);
// Gets the BackgroundImageInfo for the `basename` and calls `callback` on
// that.
void GetBackgroundImageInfo(
const base::FilePath& basename,
base::OnceCallback<void(const std::optional<BackgroundImageInfo>&)>
callback);
bool IsEligibleForBackgroundReplace();
bool IsVcBackgroundAllowedByEnterprise();
// SessionObserver:
void OnActiveUserSessionChanged(const AccountId& account_id) override;
void OnActiveUserPrefServiceChanged(PrefService* pref_service) override;
// VcEffectsDelegate:
std::optional<int> GetEffectState(VcEffectId effect_id) override;
void OnEffectControlActivated(VcEffectId effect_id,
std::optional<int> state) override;
void RecordMetricsForSetValueEffectOnClick(VcEffectId effect_id,
int state_value) const override;
void RecordMetricsForSetValueEffectOnStartup(VcEffectId effect_id,
int state_value) const override;
// media::CameraEffectObserver:
void OnCameraEffectChanged(
const cros::mojom::EffectsConfigPtr& new_effects) final;
// VideoConferenceTrayEffectsManager::Observer
// When video conference bubble is opened, update background blur effect in
// two cases:
// - Add Image state when the background replace eligible state changes from
// false -> true. This happens at most one time for enterprise users.
// - Disable/enable Image state button when background replace is already
// eligibled and enterprise policy setting changes. VC Background policy is
// dynamic-refreshed and UI should update if any changes.
void OnVideoConferenceBubbleOpened() override;
void bypass_set_camera_effects_for_testing(bool in_testing_mode) {
in_testing_mode_ = in_testing_mode;
}
void set_camera_background_img_dir_for_testing(
const base::FilePath& camera_background_img_dir) {
camera_background_img_dir_ = camera_background_img_dir;
}
void set_camera_background_run_dir_for_testing(
const base::FilePath& camera_background_run_dir) {
camera_background_run_dir_ = camera_background_run_dir;
}
// Background images are resized to have this width when they are used as icon
// in the sysui or webui.
static constexpr int kImageAsIconWidth = 512;
bool is_eligible_for_background_replace() const {
return is_eligible_for_background_replace_;
}
private:
// AutozoomObserver:
void OnAutozoomControlEnabledChanged(bool enabled) override;
// Returns the segmentation model that should be used in the effects pipeline
// based on the value of the feature flag.
cros::mojom::SegmentationModel GetSegmentationModelType();
// SetCameraEffects camera effects with `config`.
// `copy_background_image_complete_callback` is only called after background
// image is copied to `camera_background_run_dir_` which is only necessary
// when a new image is applied.
void SetCameraEffects(
cros::mojom::EffectsConfigPtr config,
bool is_initialization,
base::OnceCallback<void(bool)> copy_background_image_complete_callback);
// Called only after copying background images to
// `camera_background_run_dir_`. If `copy_succeeded`, then `new_config` will
// be applied. If `copy_succeeded` is false, but `is_initialization`, then we
// will still apply other effects except background replace.
// `copy_background_image_complete_callback` is called on `copy_succeeded`.
void OnCopyBackgroundImageFileComplete(
cros::mojom::EffectsConfigPtr new_config,
bool is_initialization,
base::OnceCallback<void(bool)> copy_background_image_complete_callback,
bool copy_succeeded);
// Called when some image content is saved inside
// `camera_background_run_dir_`. Called with actual file basename if the
// saving succeeded, otherwise called on empty path.
void OnSaveBackgroundImageFileComplete(
base::OnceCallback<void(bool)> callback,
const base::FilePath& basename);
// Constructs EffectsConfigPtr from prefs.
cros::mojom::EffectsConfigPtr GetEffectsConfigFromPref();
// Update prefs with the value in `config`.
void SetEffectsConfigToPref(cros::mojom::EffectsConfigPtr config);
// Performs any initializations needed for effects whose controls are
// exposed via the UI.
void InitializeEffectControls();
void AddBackgroundBlurEffect();
// Adds a `std::unique_ptr<VcEffectState>` to `effect`, where `effect` is
// assumed to be that of camera background blur.
void AddBackgroundBlurStateToEffect(VcHostedEffect* effect,
const gfx::VectorIcon& icon,
int state_value,
int string_id,
int view_id,
bool is_disabled_by_enterprise);
// A helper for easier binding.
void SetCameraEffectsInCameraHalDispatcherImpl(
cros::mojom::EffectsConfigPtr config);
// Used to bypass the CameraHalDispatcherImpl::SetCameraEffects for
// testing purpose.
bool in_testing_mode_ = false;
bool is_eligible_for_background_replace_ = false;
bool is_background_replace_disabled_by_enterprise_ = false;
// Directory that stores the camera background images.
base::FilePath camera_background_img_dir_;
// Directory that stores the background images for the camera module to use.
base::FilePath camera_background_run_dir_;
// Used for pref registration.
std::unique_ptr<PrefChangeRegistrar> pref_change_registrar_;
// This task runner is used to ensure `current_effects_` is always accessed
// from the same thread.
const scoped_refptr<base::SequencedTaskRunner> main_task_runner_;
// This task runner is used to run io work.
const scoped_refptr<base::SequencedTaskRunner> blocking_task_runner_;
base::ScopedObservation<media::CameraHalDispatcherImpl,
media::CameraEffectObserver>
scoped_camera_effect_observation_{this};
// Records current effects that is applied to camera hal server.
cros::mojom::EffectsConfigPtr current_effects_;
base::ScopedObservation<SessionController, SessionObserver>
session_observation_{this};
base::WeakPtrFactory<CameraEffectsController> weak_factory_{this};
};
} // namespace ash
#endif // ASH_SYSTEM_CAMERA_CAMERA_EFFECTS_CONTROLLER_H_
|