chromium/chrome/browser/ui/global_media_controls/media_notification_service.cc

// 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.

#include "chrome/browser/ui/global_media_controls/media_notification_service.h"

#include <memory>

#include "base/callback_list.h"
#include "base/metrics/histogram_functions.h"
#include "base/ranges/algorithm.h"
#include "base/unguessable_token.h"
#include "chrome/browser/feature_engagement/tracker_factory.h"
#include "chrome/browser/media/router/media_router_feature.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_finder.h"
#include "chrome/browser/ui/browser_list.h"
#include "chrome/browser/ui/global_media_controls/cast_device_list_host.h"
#include "chrome/browser/ui/global_media_controls/media_notification_device_provider_impl.h"
#include "chrome/browser/ui/global_media_controls/presentation_request_notification_producer.h"
#include "chrome/browser/ui/media_router/cast_dialog_controller.h"
#include "chrome/browser/ui/media_router/media_router_ui.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "components/feature_engagement/public/tracker.h"
#include "components/global_media_controls/public/media_dialog_delegate.h"
#include "components/global_media_controls/public/media_item_manager.h"
#include "components/global_media_controls/public/media_item_producer.h"
#include "components/media_message_center/media_notification_item.h"
#include "components/media_router/browser/media_router_factory.h"
#include "components/media_router/browser/presentation/start_presentation_context.h"
#include "components/media_router/browser/presentation/web_contents_presentation_manager.h"
#include "components/sessions/content/session_tab_helper.h"
#include "content/public/browser/audio_service.h"
#include "content/public/browser/media_session.h"
#include "content/public/browser/media_session_service.h"
#include "media/base/media_switches.h"
#include "media/remoting/device_capability_checker.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/self_owned_receiver.h"
#include "services/media_session/public/mojom/media_session.mojom.h"
#include "services/metrics/public/cpp/ukm_builders.h"
#include "services/metrics/public/cpp/ukm_recorder.h"

#if BUILDFLAG(IS_CHROMEOS_ASH)
#include "chrome/browser/ash/crosapi/crosapi_ash.h"
#include "chrome/browser/ash/crosapi/crosapi_manager.h"
#include "chrome/browser/ash/crosapi/media_ui_ash.h"
#elif BUILDFLAG(IS_CHROMEOS_LACROS)
#include "chromeos/crosapi/mojom/media_ui.mojom.h"
#include "chromeos/lacros/lacros_service.h"
#endif

namespace mojom {
DeviceListClient;
DeviceListHost;
}  // namespace mojom

namespace {

// The maximum number of actions we will record to UKM for a specific source.
constexpr int kMaxActionsRecordedToUKM =;

void CancelRequest(
    std::unique_ptr<media_router::StartPresentationContext> context,
    const std::string& message) {}

// Here we check to see if the WebContents is focused. Note that we can't just
// use |WebContentsObserver::OnWebContentsFocused()| and
// |WebContentsObserver::OnWebContentsLostFocus()| because focusing the
// MediaDialogView causes the WebContents to "lose focus", so we'd never be
// focused.
bool IsWebContentsFocused(content::WebContents* web_contents) {}

#if BUILDFLAG(IS_CHROMEOS)
crosapi::mojom::MediaUI* GetMediaUI() {
#if BUILDFLAG(IS_CHROMEOS_ASH)
  if (crosapi::CrosapiManager::IsInitialized()) {
    return crosapi::CrosapiManager::Get()->crosapi_ash()->media_ui_ash();
  }
#elif BUILDFLAG(IS_CHROMEOS_LACROS)
  if (chromeos::LacrosService::Get()->IsAvailable<crosapi::mojom::MediaUI>()) {
    return chromeos::LacrosService::Get()
        ->GetRemote<crosapi::mojom::MediaUI>()
        .get();
  }
#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
  return nullptr;
}
#endif  // BUILDFLAG(IS_CHROMEOS)

bool ShouldInitializeWithRemotePlaybackSource(
    content::WebContents* web_contents,
    media_session::mojom::RemotePlaybackMetadataPtr remote_playback_metadata) {}
}  // namespace

MediaNotificationService::MediaNotificationService(Profile* profile,
                                                   bool show_from_all_profiles)
    :{}

#if BUILDFLAG(IS_CHROMEOS)
void MediaNotificationService::ShowDialogAsh(
    std::unique_ptr<media_router::StartPresentationContext> context) {
  auto* web_contents = content::WebContents::FromRenderFrameHost(
      content::RenderFrameHost::FromID(
          context->presentation_request().render_frame_host_id));
  OnStartPresentationContextCreated(std::move(context));
  auto routes = media_router::WebContentsPresentationManager::Get(web_contents)
                    ->GetMediaRoutes();
  std::string item_id;
  // TODO(crbug.com/1462768): When `routes` is not empty, we'd ideally set
  // `item_id` to be the ID of a MediaRoute so that we'd only show the
  // corresponding notification item. However, MediaRoute IDs are not the same
  // between Lacros and Ash, so we resort to showing all the items by leaving
  // `item_id` empty.
  if (routes.empty()) {
    item_id = content::MediaSession::GetRequestIdFromWebContents(web_contents)
                  .ToString();
  }
  if (GetMediaUI()) {
    GetMediaUI()->ShowDevicePicker(item_id);
  }
}
#endif  // BUILDFLAG(IS_CHROMEOS)

MediaNotificationService::~MediaNotificationService() {}

void MediaNotificationService::Shutdown() {}

void MediaNotificationService::OnAudioSinkChosen(const std::string& item_id,
                                                 const std::string& sink_id) {}

base::CallbackListSubscription
MediaNotificationService::RegisterAudioOutputDeviceDescriptionsCallback(
    MediaNotificationDeviceProvider::GetOutputDevicesCallback callback) {}

base::CallbackListSubscription
MediaNotificationService::RegisterIsAudioOutputDeviceSwitchingSupportedCallback(
    const std::string& id,
    base::RepeatingCallback<void(bool)> callback) {}

void MediaNotificationService::OnMediaRemotingRequested(
    const std::string& item_id) {}

void MediaNotificationService::OnSinksDiscovered(const std::string& item_id) {}

void MediaNotificationService::OnMediaSessionActionButtonPressed(
    const std::string& id,
    media_session::mojom::MediaSessionAction action) {}

void MediaNotificationService::SetDialogDelegateForWebContents(
    global_media_controls::MediaDialogDelegate* delegate,
    content::WebContents* contents) {}

bool MediaNotificationService::HasActiveNotificationsForWebContents(
    content::WebContents* web_contents) const {}

bool MediaNotificationService::HasLocalCastNotifications() const {}

void MediaNotificationService::OnStartPresentationContextCreated(
    std::unique_ptr<media_router::StartPresentationContext> context) {}

void MediaNotificationService::GetDeviceListHostForSession(
    const std::string& session_id,
    mojo::PendingReceiver<mojom::DeviceListHost> host_receiver,
    mojo::PendingRemote<mojom::DeviceListClient> client_remote) {}

void MediaNotificationService::GetDeviceListHostForPresentation(
    mojo::PendingReceiver<mojom::DeviceListHost> host_receiver,
    mojo::PendingRemote<mojom::DeviceListClient> client_remote) {}

void MediaNotificationService::SetDevicePickerProvider(
    mojo::PendingRemote<global_media_controls::mojom::DevicePickerProvider>
        provider_remote) {}

std::unique_ptr<media_router::CastDialogController>
MediaNotificationService::CreateCastDialogControllerForSession(
    const std::string& id) {}

std::unique_ptr<media_router::CastDialogController>
MediaNotificationService::CreateCastDialogControllerForPresentationRequest() {}

void MediaNotificationService::CreateCastDeviceListHost(
    std::unique_ptr<media_router::CastDialogController> dialog_controller,
    mojo::PendingReceiver<mojom::DeviceListHost> host_pending_receiver,
    mojo::PendingRemote<mojom::DeviceListClient> client_remote,
    std::optional<std::string> remoting_session_id) {}

void MediaNotificationService::set_device_provider_for_testing(
    std::unique_ptr<MediaNotificationDeviceProvider> device_provider) {}

bool MediaNotificationService::HasCastNotificationsForWebContents(
    content::WebContents* web_contents) const {}

bool MediaNotificationService::HasTabMirroringSessionForWebContents(
    content::WebContents* web_contents) const {}

bool MediaNotificationService::HasActiveControllableSessionForWebContents(
    content::WebContents* web_contents) const {}

std::string
MediaNotificationService::GetActiveControllableSessionForWebContents(
    content::WebContents* web_contents) const {}

void MediaNotificationService::RemoveDeviceListHost(int host_id) {}