chromium/chrome/browser/ui/ash/birch/birch_lost_media_provider.h

// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_BROWSER_UI_ASH_BIRCH_BIRCH_LOST_MEDIA_PROVIDER_H_
#define CHROME_BROWSER_UI_ASH_BIRCH_BIRCH_LOST_MEDIA_PROVIDER_H_

#include <memory>

#include "ash/ash_export.h"
#include "ash/birch/birch_data_provider.h"
#include "ash/birch/birch_item.h"
#include "ash/system/video_conference/video_conference_common.h"
#include "base/memory/weak_ptr.h"
#include "base/task/cancelable_task_tracker.h"
#include "base/unguessable_token.h"
#include "chrome/browser/ash/video_conference/video_conference_manager_ash.h"
#include "components/favicon_base/favicon_types.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "services/media_session/public/mojom/media_controller.mojom.h"

class Profile;

namespace ash {

class VideoConferenceTrayController;

// Manages fetching tabs that are playing media by subscribing to
// MediaControllerObserver. This provider will return the most recent last
// active tab the user was on if there are multiple tabs playing media. When the
// `BirchVideoConferenceSuggestions` flag is turned on, the provider will also
// return active video conference tabs.
class ASH_EXPORT BirchLostMediaProvider
    : public BirchDataProvider,
      public media_session::mojom::MediaControllerObserver {
 public:
  explicit BirchLostMediaProvider(Profile* profile);
  BirchLostMediaProvider(const BirchLostMediaProvider&) = delete;
  BirchLostMediaProvider& operator=(const BirchLostMediaProvider&) = delete;
  ~BirchLostMediaProvider() override;

  // BirchDataProvider:
  void RequestBirchDataFetch() override;

  // media_session::mojom::MediaControllerObserver:
  void MediaSessionInfoChanged(
      media_session::mojom::MediaSessionInfoPtr session_info) override;
  void MediaSessionMetadataChanged(
      const std::optional<media_session::MediaMetadata>& metadata) override;
  void MediaSessionActionsChanged(
      const std::vector<media_session::mojom::MediaSessionAction>& actions)
      override;
  void MediaSessionChanged(
      const std::optional<base::UnguessableToken>& request_id) override;
  void MediaSessionPositionChanged(
      const std::optional<media_session::MediaPosition>& position) override;

 private:
  friend class BirchKeyedServiceTest;

  // This callback executes once video conference app data is available from the
  // `video_conference_controller_`, and passes vc app data to the birch model.
  void OnVideoConferencingDataAvailable(
      VideoConferenceManagerAsh::MediaApps media_apps);

  // Passes media apps data that is observed from MediaSessionMetaDataChanged()
  // to the birch model.
  void SetMediaAppsFromMediaController();

  // Handles activation events by either returning to a specific video
  // conference session or calling `Raise()` on the media controller to activate
  // the correct media tab. A valid `vc_id` is required to return to the vc
  // session; otherwise, we can infer that the item is a media tab.
  void OnItemPressed(std::optional<base::UnguessableToken> vc_id);

  void set_fake_media_controller_for_testing(
      mojo::Remote<media_session::mojom::MediaController> fake_controller) {
    media_controller_remote_ = std::move(fake_controller);
  }

  void set_fake_video_conference_controller_for_testing(
      VideoConferenceTrayController* fake_controller) {
    video_conference_controller_ = fake_controller;
  }

  // The media controller that is responsible for executing media actions.
  mojo::Remote<media_session::mojom::MediaController> media_controller_remote_;

  // The mojo receiver to observe changes from `MediaControllerObserver`.
  mojo::Receiver<media_session::mojom::MediaControllerObserver>
      media_observer_receiver_{this};

  // Whether the media is playing (it might be paused or stopped).
  bool is_playing_ = false;

  // The title of the media item.
  std::u16string media_title_;

  // The origin source of the media item. This will assist in the creation of a
  // complete GURL source on birch item creation.
  std::u16string source_url_;

  // The type of the secondary icon. Default to no icon type.
  SecondaryIconType secondary_icon_type_ = SecondaryIconType::kNoIcon;

  // `VideoConferenceTrayController` used to get active video conference
  // session.
  raw_ptr<VideoConferenceTrayController> video_conference_controller_;

  // Used for loading favicons.
  base::CancelableTaskTracker cancelable_task_tracker_;

  const raw_ptr<Profile> profile_;

  base::WeakPtrFactory<BirchLostMediaProvider> weak_factory_{this};
};

}  // namespace ash

#endif  // CHROME_BROWSER_UI_ASH_BIRCH_BIRCH_LOST_MEDIA_PROVIDER_H_