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
  302
  303
  304
  305
  306
  307
  308
  309
  310
  311
  312
  313
  314
  315
  316
  317
  318
  319
  320
  321
  322
  323
  324
  325
  326
  327
  328
  329
  330
  331
  332
  333
  334
  335
  336
  337
  338
  339
  340
  341
  342
  343
  344
  345
  346
  347
  348
  349
  350
  351
  352
  353
  354
  355
  356
  357
  358
  359
  360
  361
  362
  363
  364
  365
  366
  367
  368
  369
  370
  371
  372
  373
  374
  375
  376
  377
  378
  379
  380
  381
  382
  383
  384
  385
  386
  387
  388
  389
  390
  391
  392
  393
  394
  395
  396
  397
  398
  399
  400
  401
  402

ash / ambient / ambient_controller.h [blame]

// Copyright 2019 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_AMBIENT_AMBIENT_CONTROLLER_H_
#define ASH_AMBIENT_AMBIENT_CONTROLLER_H_

#include <memory>
#include <utility>
#include <vector>

#include "ash/ambient/ambient_access_token_controller.h"
#include "ash/ambient/ambient_photo_controller.h"
#include "ash/ambient/ambient_ui_launcher.h"
#include "ash/ambient/ambient_view_delegate_impl.h"
#include "ash/ambient/ambient_weather_controller.h"
#include "ash/ambient/managed/screensaver_images_policy_handler.h"
#include "ash/ambient/model/ambient_backend_model.h"
#include "ash/ambient/resources/ambient_dlc_background_installer.h"
#include "ash/ambient/ui/ambient_view_delegate.h"
#include "ash/ash_export.h"
#include "ash/assistant/model/assistant_interaction_model_observer.h"
#include "ash/public/cpp/ambient/ambient_ui_model.h"
#include "ash/public/cpp/screen_backlight_observer.h"
#include "ash/public/cpp/session/session_observer.h"
#include "ash/session/session_controller_impl.h"
#include "ash/system/power/backlights_forced_off_setter.h"
#include "ash/system/power/power_status.h"
#include "base/cancelable_callback.h"
#include "base/gtest_prod_util.h"
#include "base/memory/weak_ptr.h"
#include "base/scoped_observation.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "chromeos/dbus/power/power_manager_client.h"
#include "components/prefs/pref_change_registrar.h"
#include "components/prefs/pref_service.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "services/device/public/mojom/fingerprint.mojom.h"
#include "services/device/public/mojom/wake_lock.mojom.h"
#include "ui/base/user_activity/user_activity_detector.h"
#include "ui/base/user_activity/user_activity_observer.h"
#include "ui/events/event_handler.h"
#include "ui/views/widget/widget.h"

class PrefRegistrySimple;

namespace ash {

// Delay for dismissing screensaver preview on mouse move.
constexpr base::TimeDelta kDismissPreviewOnMouseMoveDelay = base::Seconds(3);

class AmbientBackendController;
class AmbientContainerView;
class AmbientPhotoController;
class AmbientSessionMetricsRecorder;
class AmbientUiSettings;

// Class to handle all ambient mode functionalities.
class ASH_EXPORT AmbientController
    : public AmbientUiModelObserver,
      public ScreenBacklightObserver,
      public SessionObserver,
      public PowerStatus::Observer,
      public chromeos::PowerManagerClient::Observer,
      public device::mojom::FingerprintObserver,
      public ui::UserActivityObserver,
      public ui::EventHandler,
      public AssistantInteractionModelObserver,
      public AmbientUiLauncher::Observer {
 public:
  static void RegisterProfilePrefs(PrefRegistrySimple* registry);

  explicit AmbientController(
      mojo::PendingRemote<device::mojom::Fingerprint> fingerprint);

  AmbientController(const AmbientController&) = delete;
  AmbientController& operator=(const AmbientController&) = delete;

  ~AmbientController() override;

  // AmbientUiModelObserver:
  void OnAmbientUiVisibilityChanged(AmbientUiVisibility visibility) override;

  // Screen backlights off observer:
  void OnBacklightsForcedOffChanged(bool backlights_forced_off) override;

  // SessionObserver:
  void OnLockStateChanged(bool locked) override;
  void OnActiveUserPrefServiceChanged(PrefService* pref_service) override;
  void OnSigninScreenPrefServiceInitialized(PrefService* pref_service) override;

  // PowerStatus::Observer:
  void OnPowerStatusChanged() override;

  // chromeos::PowerManagerClient::Observer:
  void ScreenIdleStateChanged(
      const power_manager::ScreenIdleState& idle_state) override;
  void SuspendImminent(power_manager::SuspendImminent::Reason reason) override;
  void SuspendDone(base::TimeDelta sleep_duration) override;

  // fingerprint::mojom::FingerprintObserver:
  void OnAuthScanDone(
      const device::mojom::FingerprintMessagePtr msg,
      const base::flat_map<std::string, std::vector<std::string>>& matches)
      override;
  void OnSessionFailed() override {}
  void OnRestarted() override {}
  void OnStatusChanged(device::mojom::BiometricsManagerStatus state) override {}
  void OnEnrollScanDone(device::mojom::ScanResult scan_result,
                        bool enroll_session_complete,
                        int percent_complete) override {}

  // ui::UserActivityObserver:
  void OnUserActivity(const ui::Event* event) override;

  // ui::EventHandler:
  void OnKeyEvent(ui::KeyEvent* event) override;
  void OnMouseEvent(ui::MouseEvent* event) override;
  void OnTouchEvent(ui::TouchEvent* event) override;

  // AssistantInteractionModelObserver:
  void OnInteractionStateChanged(InteractionState interaction_state) override;

  // AmbientUiLauncher::Observer:
  void OnReadyStateChanged(bool is_ready) override;

  // Invoked by the `LockScreen` to notify ambient mode that either the login or
  // lock screen has been created.
  void OnLoginOrLockScreenCreated();

  // Set the ui state to begin showing ambient mode. After calling this
  // function, there will be a delay while content downloads or reads from disk
  // until ambient mode widget is actually constructed.
  void SetUiVisibilityShouldShow();

  // Set the ui state to begin showing preview ambient mode. After calling this
  // function, there will be a delay while content downloads or reads from disk
  // until ambient mode widget is actually constructed.
  void SetUiVisibilityPreview();

  // Ui will be enabled but media will not load and UI will not be shown
  // immediately. Typically used by lock screen. If there is no user activity Ui
  // will be transitioned to shown state after a short delay.
  void SetUiVisibilityHidden();

  void SetUiVisibilityClosed(bool immediately = false);

  // |minutes| is the number of minutes to run screen saver before putting the
  // device into sleep. |minutes| with a value 0 means forever.
  void SetScreenSaverDuration(int minutes);

  void StartTimerToReleaseWakeLock();

  // Returns true if current state should be visible in UI. When this becomes
  // true, there is a delay while media loads before `IsAmbientRunning` will
  // also return true.
  bool ShouldShowAmbientUi() const;

  // Returns true if ambient is actually started and visible. Implies
  // `ShouldShowAmbientUi`. Media has already loaded and widget is
  // constructed.
  bool IsShowing() const;

  void RequestAccessToken(
      AmbientAccessTokenController::AccessTokenCallback callback,
      bool may_refresh_token_on_lock = false);

  // Creates a widget and |AmbientContainerView| for the container.
  std::unique_ptr<views::Widget> CreateWidget(aura::Window* container);

  AmbientBackendModel* GetAmbientBackendModel();
  AmbientWeatherModel* GetAmbientWeatherModel();

  AmbientBackendController* ambient_backend_controller() {
    return ambient_backend_controller_.get();
  }

  AmbientUiLauncher* ambient_ui_launcher() {
    return ambient_ui_launcher_.get();
  }

  AmbientWeatherController* ambient_weather_controller() {
    return ambient_weather_controller_.get();
  }

  AmbientUiModel* ambient_ui_model() { return &ambient_ui_model_; }

  AmbientViewDelegate* ambient_view_delegate() { return &delegate_; }

  AmbientAccessTokenController* access_token_controller() {
    return &access_token_controller_;
  }

  void set_backend_controller_for_testing(
      std::unique_ptr<AmbientBackendController> backend_controller) {
    ambient_backend_controller_ = std::move(backend_controller);
  }

 private:
  // Enum to indicate which state the lock screen is in. This is used
  // by `OnLoginLockScreenStateChanged` method as a parameter to pass
  // the correct information to the method.
  enum LockScreenState { kLogin, kLocked, kUnlocked };

  // Tracks the progression of states with `AmbientUiLauncher`.
  enum class AmbientUiLauncherState {
    // Waiting for `Initialize()` to finish.
    kInitializing,
    // `Initialize()` has completed successfully.
    kRendering,
    // After `Finalize()` (not in the middle of launching or rendering an
    // ambient session).
    kInactive,
  };

  friend class AmbientAshTestBase;
  friend class AmbientControllerTest;
  FRIEND_TEST_ALL_PREFIXES(AmbientControllerTest,
                           BindsObserversWhenAmbientEnabled);
  FRIEND_TEST_ALL_PREFIXES(AmbientControllerTest, BindsObserversWhenAmbientOn);

  AmbientPhotoController* ambient_photo_controller() {
    return ambient_ui_launcher_->GetAmbientPhotoController();
  }

  // Hide or close Ambient mode UI.
  void DismissUI();

  // Creates and shows a full-screen widget for each root window to show the
  // ambient UI.
  void CreateAndShowWidgets();

  void StartRefreshingImages();
  void StopScreensaver();
  void MaybeStartScreenSaver();
  void MaybeDismissUIOnMouseMove();
  AmbientUiSettings GetCurrentUiSettings() const;

  // Invoked when the auto-show timer in |InactivityMonitor| gets fired after
  // device being inactive for a specific amount of time.
  void OnAutoShowTimeOut();

  // Creates (if not created) and acquires |wake_lock_|. Unbalanced call
  // without subsequently |ReleaseWakeLock| will have no effect.
  void AcquireWakeLock();

  // Release |wake_lock_|. Unbalanced release call will have no effect.
  void ReleaseWakeLock();

  void CloseAllWidgets(bool immediately);

  // Start receiving mouse/key/touch events from `ash::Shell`.
  void SetUpPreTargetHandler();

  // Stop receiving mouse/key/touch events from `ash::Shell`.
  void ClearPreTargetHandler();

  // Removes any and all ambient mode ui model related settings pref observers
  void RemoveAmbientModeSettingsPrefObservers();

  // Adds/Removes pref observers
  void AddManagedScreensaverPolicyPrefObservers();
  void AddConsumerPrefObservers();

  // Invoked when the Ambient mode prefs state changes.
  void OnEnabledPrefChanged();
  void OnLockScreenInactivityTimeoutPrefChanged();
  void OnLockScreenBackgroundTimeoutPrefChanged();
  void OnPhotoRefreshIntervalPrefChanged();
  void OnAmbientUiSettingsChanged();
  void OnAnimationPlaybackSpeedChanged();

  // Resets the resources allocated by the ambient controller.
  void ResetAmbientControllerResources();

  // Invoked when preferences change via policy updates.
  void OnManagedScreensaverLockScreenIdleTimeoutPrefChanged();
  void OnManagedScreensaverPhotoRefreshIntervalPrefChanged();

  void CreateUiLauncher();
  void DestroyUiLauncher();
  bool IsUiLauncherActive() const;
  void OnUiLauncherInitialized(bool success);

  void OnLoginLockStateChanged(LockScreenState state);

  LockScreenState GetLockScreenState();

  // Returns the active pref change registrar. Note: The registar for user
  // profile `pref_change_registrar_` will always be the active pref change
  // registrar when the user is logged in, when the user is not logged in
  // this will return the `sign_in_pref_change_registrar_`.
  PrefChangeRegistrar* GetActivePrefChangeRegistrar();

  void MaybeStopUiEventPropagation(ui::Event* event);

  AmbientViewDelegateImpl delegate_{this};
  AmbientUiModel ambient_ui_model_;

  AmbientAccessTokenController access_token_controller_;
  AmbientBackgroundDlcInstaller background_dlc_installer_;
  std::unique_ptr<AmbientBackendController> ambient_backend_controller_;
  std::unique_ptr<AmbientWeatherController> ambient_weather_controller_;

  // Monitors the device inactivity and controls the auto-show of ambient.
  base::OneShotTimer inactivity_timer_;

  // Monitors the running time since screen saver starts.
  base::OneShotTimer screensaver_running_timer_;

  // Lazily initialized on the first call of |AcquireWakeLock|.
  mojo::Remote<device::mojom::WakeLock> wake_lock_;

  base::ScopedObservation<AmbientUiModel, AmbientUiModelObserver>
      ambient_ui_model_observer_{this};
  base::ScopedObservation<SessionControllerImpl, SessionObserver>
      session_observer_{this};
  base::ScopedObservation<PowerStatus, PowerStatus::Observer>
      power_status_observer_{this};
  base::ScopedObservation<chromeos::PowerManagerClient,
                          chromeos::PowerManagerClient::Observer>
      power_manager_client_observer_{this};
  base::ScopedObservation<ui::UserActivityDetector, ui::UserActivityObserver>
      user_activity_observer_{this};

  base::ScopedObservation<BacklightsForcedOffSetter, ScreenBacklightObserver>
      backlights_forced_off_observation_{this};

  // Observes user profile prefs for ambient.
  std::unique_ptr<PrefChangeRegistrar> pref_change_registrar_;

  // Observes sign-in profile prefs for ambient mode device policy changes.
  std::unique_ptr<PrefChangeRegistrar> sign_in_pref_change_registrar_;

  // Records the time when preview widgets are created.
  base::Time preview_widget_created_at_;

  base::OneShotTimer delayed_lock_timer_;

  mojo::Remote<device::mojom::Fingerprint> fingerprint_;
  mojo::Receiver<device::mojom::FingerprintObserver>
      fingerprint_observer_receiver_{this};

  // Set when |SuspendImminent| is called and cleared when |SuspendDone| is
  // called. Used to prevent Ambient mode from reactivating while device is
  // going to suspend.
  bool is_suspend_imminent_ = false;

  // Set to the off value in |ScreenIdleState| when ScreenIdleState() is
  // called. Used to prevent Ambient mode starting after screen is off.
  bool is_screen_off_ = false;

  bool close_widgets_immediately_ = false;

  // ui::EventType::kMouseMove is fired before many mouse events. An event is an
  // actual mouse move event only if the last event was
  // ui::EventType::kMouseMove too. Used to keep track of the last event and
  // identify a true mouse move event.
  // TODO(safarli): Remove this workaround when b/266234711 is fixed.
  bool last_mouse_event_was_move_ = false;

  // Flag used to handle calls to OnEnabledPrefChanged initializing
  // the controller.
  bool is_initialized_ = false;

  // Flag used to monitor if receiving events, such as mouse/key/touch, from
  // `ash::Shell`.
  bool is_receiving_pretarget_events_ = false;

  AmbientUiLauncherState ui_launcher_state_ = AmbientUiLauncherState::kInactive;

  std::unique_ptr<AmbientSessionMetricsRecorder> session_metrics_recorder_;

  // The policy handler for downloading policy set images. This lives in the
  // ambient controller because it needs to outlive the disable policy update
  // so that it is able to actually clean up the images when the policy is
  // disabled.
  //
  // The sequence of operations are as follows which happen on policy update
  // 1. Admin sets ambient mode policy to disabled
  // 2. Ambient mode is dismissed
  // 3. ManagedSlideshowUiLauncher is destroyed
  // 4. Other policy values (photo interval, inactivity time, images) are unset
  //    and sent as part of the policy update.
  //
  // Now at point 4 the policy handler needs to be alive so that it can react to
  // the unset images call and clean up the images from disk.
  std::unique_ptr<ScreensaverImagesPolicyHandler>
      screensaver_images_policy_handler_;

  std::unique_ptr<AmbientUiLauncher> ambient_ui_launcher_;
  base::CancelableOnceCallback<void(bool)> ui_launcher_init_callback_;

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

}  // namespace ash

#endif  // ASH_AMBIENT_AMBIENT_CONTROLLER_H_