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

ash / system / video_conference / bubble / vc_tile_ui_controller.h [blame]

// Copyright 2023 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_VIDEO_CONFERENCE_BUBBLE_VC_TILE_UI_CONTROLLER_H_
#define ASH_SYSTEM_VIDEO_CONFERENCE_BUBBLE_VC_TILE_UI_CONTROLLER_H_

#include <string>

#include "ash/ash_export.h"
#include "ash/system/unified/feature_tile.h"
#include "ash/system/video_conference/effects/video_conference_tray_effects_manager.h"
#include "ash/system/video_conference/effects/video_conference_tray_effects_manager_types.h"
#include "base/containers/flat_set.h"
#include "base/memory/weak_ptr.h"
#include "chromeos/ash/components/dbus/dlcservice/dlcservice.pb.h"
#include "chromeos/ash/components/dbus/dlcservice/dlcservice_client.h"

namespace ash {

class VcEffectState;
enum class VcEffectId;

namespace video_conference {

// The controller for the UI of toggle tiles in the VC controls bubble. There is
// one controller per tile. Non-UI logic for the tiles is handled by
// `ash::VcEffectsDelegate`.
//
// Note: This class is only used when `VcDlcUi` is enabled.
class ASH_EXPORT VcTileUiController
    : public DlcserviceClient::Observer,
      public VideoConferenceTrayEffectsManager::Observer {
 public:
  explicit VcTileUiController(const VcHostedEffect* effect);
  VcTileUiController(const VcTileUiController&) = delete;
  VcTileUiController& operator=(const VcTileUiController&) = delete;
  ~VcTileUiController() override;

  // Creates and returns the `FeatureTile` associated with this controller.
  std::unique_ptr<FeatureTile> CreateTile();

  // Returns the effect id associated with this controller, for testing purposes
  // only.
  VcEffectId effect_id_for_testing() const { return effect_id_; }

 private:
  friend class VcTileUiControllerTest;

  // Starts a request for DLC download state. Multiple DLCs may be available.
  class DlcDownloadStateRequest {
   public:
    DlcDownloadStateRequest(
        const base::flat_set<std::string>& dlc_ids,
        base::OnceCallback<void(FeatureTile::DownloadState download_state,
                                int progress)> set_progress_callback);
    DlcDownloadStateRequest(const DlcDownloadStateRequest&) = delete;
    DlcDownloadStateRequest& operator=(const DlcDownloadStateRequest&) = delete;
    ~DlcDownloadStateRequest();

   private:
    // A collection of information related to the download state of a particular
    // DLC.
    struct DlcDownloadState {
      const std::string id;
      const std::string error_code;
      const dlcservice::DlcState dlc_state;
    };

    // Callback passed to `DlcServiceClient` to record DlcState. May be called
    // multiple times if multiple `dlc_id`'s need to be checked.
    void OnDlcStateRetrieved(
        std::string dlc_id,
        base::OnceCallback<void(DlcDownloadState)> merge_callback,
        std::string_view error,
        const dlcservice::DlcState& dlc_state);

    // Callback called when all dlc states have been retrieved.
    void OnAllDlcStatesRetrieved(
        std::vector<DlcDownloadState> dlc_download_states);

    // Callback called after all DLC states are received. Results in destruction
    // of the `DlcDownloadStateRequest`.
    base::OnceCallback<void(FeatureTile::DownloadState download_state,
                            int progress)>
        set_progress_callback_;

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

  // DlcserviceClient::Observer:
  void OnDlcStateChanged(const dlcservice::DlcState& dlc_state) override;

  // VideoConferenceTrayEffectsManager::Observer:
  void OnEffectChanged(VcEffectId effect_id, bool is_on) override;

  // Called when the `FeatureTile` associated with this controller is pressed.
  void OnPressed(const ui::Event& event);

  // Sets the tooltip text based on the associated tile's toggle state.
  void UpdateTooltip();

  // Tracks the toggling behavior. Obtains the histogram name with the help of
  // `GetEffectId()`.
  void TrackToggleUMA(bool target_toggle_state);

  // Plays a haptic effect based on `target_toggle_state`.
  void PlayToggleHaptic(bool target_toggle_state);

  // Updates the UI of the tile managed by this controller based on the download
  // progress of the tile's associated DLC.
  void UpdateDlcDownloadUi();

  // Callback passed to `dlc_download_state_request_`, called when all download
  // states related to `dlc_ids_` have been fetched.
  void OnDlcDownloadStateFetched(FeatureTile::DownloadState download_state,
                                 int progress);

  // A weak pointer to the `FeatureTile` associated with this controller. Note
  // that this is guaranteed to be nullptr before `CreateTile()` is called, and
  // may even be nullptr after `CreateTile()` is called (the tile is owned by
  // the Views hierarchy, not this controller).
  base::WeakPtr<FeatureTile> tile_ = nullptr;

  // The effect id which is used for UMA tracking.
  VcEffectId effect_id_;

  // Information about the associated video conferencing effect needed to
  // display the UI of the tile controlled by this controller. WeakPtr's are
  // saved because the `VcTileUiController` may outlive its dependencies.
  base::WeakPtr<const VcEffectState> effect_state_;
  base::WeakPtr<const VcHostedEffect> effect_;

  // The initial label for `effect_state_`, used for debugging.
  std::u16string effect_state_label_for_debug_;

  // A list of ids for the DLCs associated with the tile managed by this
  // controller. This is empty for tiles not associated with any DLC.
  base::flat_set<std::string> dlc_ids_;

  // A request which asynchronously fetches 0->many DLC download states, and
  // updates the controller on combined progress or any errors.
  std::unique_ptr<DlcDownloadStateRequest> dlc_download_state_request_;

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

}  // namespace video_conference

}  // namespace ash

#endif  // ASH_SYSTEM_VIDEO_CONFERENCE_BUBBLE_VC_TILE_UI_CONTROLLER_H_