Skip to content

Commit

Permalink
[GMC+Cast] Use CastDeviceListHost and Mojo interfaces
Browse files Browse the repository at this point in the history
Previous CL in this series: http://crrev.com/c/4191629

There's no behavioral change in this CL; we're just making existing classes use the Mojo interfaces introduced in the previous CL:

- Make MediaItemUIDeviceSelectorView implement mojo::DeviceClient. This goes on the Ash side of the Ash-Lacros split

- Delete parts of MediaItemUIDeviceSelectorView that moved to CastDeviceListHost, which is on the Lacros side

- Make MediaNotificationService implement mojo::DeviceService. This lives on the Lacros side.

- Make CastDeviceEntryView use mojo::Device instead of UIMediaSink

Bug: 1407071
Change-Id: I7c4c2b45a01366e3ffe39bbb278d58a706b6a849
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4179425
Reviewed-by: Muyao Xu <muyaoxu@google.com>
Commit-Queue: Takumi Fujimoto <takumif@chromium.org>
Reviewed-by: Tommy Steimel <steimel@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1104888}
  • Loading branch information
takumif authored and Chromium LUCI CQ committed Feb 14, 2023
1 parent ae4886a commit 86a6587
Show file tree
Hide file tree
Showing 19 changed files with 535 additions and 414 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,7 @@ class MediaItemUIDeviceSelectorDelegate {

// Used by `MediaItemUIDeviceSelectorView` to send commands to MediaController
// to request starting a Remote Playback session.
// Return true when the request is sent to MediaController successfully.
virtual bool OnMediaRemotingRequested(const std::string& item_id) = 0;
virtual void OnMediaRemotingRequested(const std::string& item_id) = 0;

protected:
virtual ~MediaItemUIDeviceSelectorDelegate() = default;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@
#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/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/global_media_controls/public/media_dialog_delegate.h"
Expand All @@ -30,10 +32,16 @@
#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/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"

namespace mojom {
using global_media_controls::mojom::DeviceListClient;
using global_media_controls::mojom::DeviceListHost;
} // namespace mojom

namespace {

// The maximum number of actions we will record to UKM for a specific source.
Expand All @@ -55,15 +63,15 @@ void CancelRequest(
bool IsWebContentsFocused(content::WebContents* web_contents) {
DCHECK(web_contents);
Browser* browser = chrome::FindBrowserWithWebContents(web_contents);
if (!browser)
if (!browser) {
return false;

}
// If the given WebContents is not in the focused window, then it's not
// focused. Note that we know a Browser is focused because otherwise the user
// could not interact with the MediaDialogView.
if (BrowserList::GetInstance()->GetLastActive() != browser)
if (BrowserList::GetInstance()->GetLastActive() != browser) {
return false;

}
return browser->tab_strip_model()->GetActiveWebContents() == web_contents;
}

Expand Down Expand Up @@ -126,9 +134,9 @@ void MediaNotificationService::Shutdown() {
// |cast_notification_producer_| and
// |presentation_request_notification_producer_| depend on MediaRouter,
// which is another keyed service.
if (cast_notification_producer_)
if (cast_notification_producer_) {
item_manager_->RemoveItemProducer(cast_notification_producer_.get());

}
if (presentation_request_notification_producer_) {
item_manager_->RemoveItemProducer(
presentation_request_notification_producer_.get());
Expand All @@ -146,9 +154,10 @@ void MediaNotificationService::OnAudioSinkChosen(const std::string& item_id,
base::CallbackListSubscription
MediaNotificationService::RegisterAudioOutputDeviceDescriptionsCallback(
MediaNotificationDeviceProvider::GetOutputDevicesCallback callback) {
if (!device_provider_)
if (!device_provider_) {
device_provider_ = std::make_unique<MediaNotificationDeviceProviderImpl>(
content::CreateAudioSystemForAudioService());
}
return device_provider_->RegisterOutputDeviceDescriptionsCallback(
std::move(callback));
}
Expand All @@ -162,29 +171,31 @@ MediaNotificationService::RegisterIsAudioOutputDeviceSwitchingSupportedCallback(
id, std::move(callback));
}

bool MediaNotificationService::OnMediaRemotingRequested(
void MediaNotificationService::OnMediaRemotingRequested(
const std::string& item_id) {
auto item = media_session_item_producer_->GetMediaItem(item_id);
return item ? item->RequestMediaRemoting() : false;
if (item) {
item->RequestMediaRemoting();
}
}

void MediaNotificationService::OnMediaSessionActionButtonPressed(
const std::string& id,
media_session::mojom::MediaSessionAction action) {
auto* web_contents = content::MediaSession::GetWebContentsFromRequestId(id);
if (!web_contents)
if (!web_contents) {
return;

}
base::UmaHistogramBoolean("Media.GlobalMediaControls.UserActionFocus",
IsWebContentsFocused(web_contents));

ukm::UkmRecorder* recorder = ukm::UkmRecorder::Get();
ukm::SourceId source_id =
web_contents->GetPrimaryMainFrame()->GetPageUkmSourceId();

if (++actions_recorded_to_ukm_[source_id] > kMaxActionsRecordedToUKM)
if (++actions_recorded_to_ukm_[source_id] > kMaxActionsRecordedToUKM) {
return;

}
ukm::builders::Media_GlobalMediaControls_ActionButtonPressed(source_id)
.SetMediaSessionAction(static_cast<int64_t>(action))
.Record(recorder);
Expand Down Expand Up @@ -274,18 +285,32 @@ void MediaNotificationService::OnStartPresentationContextCreated(
}
}

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

void MediaNotificationService::GetDeviceListHostForPresentation(
mojo::PendingReceiver<mojom::DeviceListHost> host_receiver,
mojo::PendingRemote<mojom::DeviceListClient> client_remote) {
CreateCastDeviceListHost(CreateCastDialogControllerForPresentationRequest(),
std::move(host_receiver), std::move(client_remote));
}

std::unique_ptr<media_router::CastDialogController>
MediaNotificationService::CreateCastDialogControllerForSession(
const std::string& id) {
auto* web_contents = content::MediaSession::GetWebContentsFromRequestId(id);
if (!web_contents)
if (!web_contents) {
return nullptr;

}
if (context_) {
return media_router::MediaRouterUI::CreateWithStartPresentationContext(
web_contents, std::move(context_));
}

// Initialize MediaRouterUI with Remote Playback Media Source if there is no
// default PresentationRequest associated with `web_contents`.
if (base::FeatureList::IsEnabled(media::kMediaRemotingWithoutFullscreen)) {
Expand Down Expand Up @@ -316,9 +341,9 @@ std::unique_ptr<media_router::CastDialogController>
MediaNotificationService::CreateCastDialogControllerForPresentationRequest() {
auto* web_contents =
presentation_request_notification_producer_->GetWebContents();
if (!web_contents)
if (!web_contents) {
return nullptr;

}
if (!presentation_request_notification_producer_->GetNotificationItem()
->is_default_presentation_request()) {
return media_router::MediaRouterUI::CreateWithStartPresentationContext(
Expand All @@ -330,6 +355,24 @@ MediaNotificationService::CreateCastDialogControllerForPresentationRequest() {
web_contents);
}

void MediaNotificationService::CreateCastDeviceListHost(
std::unique_ptr<media_router::CastDialogController> dialog_controller,
mojo::PendingReceiver<mojom::DeviceListHost> host_receiver,
mojo::PendingRemote<mojom::DeviceListClient> client_remote) {
if (!dialog_controller) {
// We discard the PendingReceiver/Remote here, and if they have disconnect
// handlers set, those get called.
return;
}
mojo::MakeSelfOwnedReceiver(
std::make_unique<CastDeviceListHost>(
std::move(dialog_controller), std::move(client_remote),
base::BindRepeating(
&MediaNotificationService::OnMediaRemotingRequested,
weak_ptr_factory_.GetWeakPtr())),
std::move(host_receiver));
}

void MediaNotificationService::set_device_provider_for_testing(
std::unique_ptr<MediaNotificationDeviceProvider> device_provider) {
device_provider_ = std::move(device_provider);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,11 @@
#include "chrome/browser/ui/global_media_controls/presentation_request_notification_producer.h"
#include "components/global_media_controls/public/media_session_item_producer.h"
#include "components/global_media_controls/public/media_session_item_producer_observer.h"
#include "components/global_media_controls/public/mojom/device_service.mojom.h"
#include "components/keyed_service/core/keyed_service.h"
#include "content/public/browser/presentation_observer.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "services/metrics/public/cpp/ukm_source_id.h"
#include "third_party/abseil-cpp/absl/types/optional.h"

Expand All @@ -39,7 +42,8 @@ class CastDialogController;
class MediaNotificationService
: public KeyedService,
public MediaItemUIDeviceSelectorDelegate,
public global_media_controls::MediaSessionItemProducerObserver {
public global_media_controls::MediaSessionItemProducerObserver,
public global_media_controls::mojom::DeviceService {
public:
MediaNotificationService(Profile* profile, bool show_from_all_profiles);
MediaNotificationService(const MediaNotificationService&) = delete;
Expand All @@ -63,7 +67,7 @@ class MediaNotificationService
RegisterIsAudioOutputDeviceSwitchingSupportedCallback(
const std::string& id,
base::RepeatingCallback<void(bool)> callback) override;
bool OnMediaRemotingRequested(const std::string& item_id) override;
void OnMediaRemotingRequested(const std::string& item_id) override;

// global_media_controls::MediaSessionItemProducerObserver:
void OnMediaSessionActionButtonPressed(
Expand All @@ -85,6 +89,31 @@ class MediaNotificationService
void OnStartPresentationContextCreated(
std::unique_ptr<media_router::StartPresentationContext> context);

// global_media_controls::mojom::DeviceService:
void GetDeviceListHostForSession(
const std::string& session_id,
mojo::PendingReceiver<global_media_controls::mojom::DeviceListHost>
host_receiver,
mojo::PendingRemote<global_media_controls::mojom::DeviceListClient>
client_remote) override;
void GetDeviceListHostForPresentation(
mojo::PendingReceiver<global_media_controls::mojom::DeviceListHost>
host_receiver,
mojo::PendingRemote<global_media_controls::mojom::DeviceListClient>
client_remote) override;

void set_device_provider_for_testing(
std::unique_ptr<MediaNotificationDeviceProvider> device_provider);

private:
friend class MediaNotificationProviderImplTest;
friend class MediaNotificationServiceTest;
friend class MediaNotificationServiceCastTest;
friend class MediaToolbarButtonControllerTest;
friend class PresentationRequestNotificationProducerTest;
FRIEND_TEST_ALL_PREFIXES(MediaNotificationServiceCastTest,
CreateCastDialogControllerWithRemotePlayback);

// Instantiates a MediaRouterViewsUI object associated with the Session with
// the given |session_id|.
std::unique_ptr<media_router::CastDialogController>
Expand All @@ -96,15 +125,12 @@ class MediaNotificationService
std::unique_ptr<media_router::CastDialogController>
CreateCastDialogControllerForPresentationRequest();

void set_device_provider_for_testing(
std::unique_ptr<MediaNotificationDeviceProvider> device_provider);

private:
friend class MediaNotificationProviderImplTest;
friend class MediaNotificationServiceTest;
friend class MediaNotificationServiceCastTest;
friend class MediaToolbarButtonControllerTest;
friend class PresentationRequestNotificationProducerTest;
void CreateCastDeviceListHost(
std::unique_ptr<media_router::CastDialogController> dialog_controller,
mojo::PendingReceiver<global_media_controls::mojom::DeviceListHost>
host_receiver,
mojo::PendingRemote<global_media_controls::mojom::DeviceListClient>
client_remote);

// True if there are cast notifications associated with |web_contents|.
bool HasCastNotificationsForWebContents(
Expand Down

0 comments on commit 86a6587

Please sign in to comment.