File: camera_effects_controller.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (301 lines) | stat: -rw-r--r-- 11,627 bytes parent folder | download | duplicates (6)
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_