Commit 91eef299 authored by Takumi Fujimoto's avatar Takumi Fujimoto Committed by Chromium LUCI CQ

Create the MediaNotificatoinProvider interface

Part 1 of MediaNotificationService refactoring. Create an interface and
make CastMediaNotificationProvider and
PresentationRequestNotificationProvider implement it.

Bug: 1021643
Change-Id: I899d0430a59a7432ed2d55bcbc23af3cb8405a07
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2606650
Commit-Queue: Takumi Fujimoto <takumif@chromium.org>
Reviewed-by: default avatarTommy Steimel <steimel@chromium.org>
Cr-Commit-Position: refs/heads/master@{#844342}
parent 1d302153
...@@ -994,6 +994,7 @@ static_library("ui") { ...@@ -994,6 +994,7 @@ static_library("ui") {
"global_media_controls/media_notification_device_provider.h", "global_media_controls/media_notification_device_provider.h",
"global_media_controls/media_notification_device_provider_impl.cc", "global_media_controls/media_notification_device_provider_impl.cc",
"global_media_controls/media_notification_device_provider_impl.h", "global_media_controls/media_notification_device_provider_impl.h",
"global_media_controls/media_notification_producer.h",
"global_media_controls/media_notification_service.cc", "global_media_controls/media_notification_service.cc",
"global_media_controls/media_notification_service.h", "global_media_controls/media_notification_service.h",
"global_media_controls/media_notification_service_factory.cc", "global_media_controls/media_notification_service_factory.cc",
......
...@@ -54,6 +54,23 @@ CastMediaNotificationProvider::CastMediaNotificationProvider( ...@@ -54,6 +54,23 @@ CastMediaNotificationProvider::CastMediaNotificationProvider(
CastMediaNotificationProvider::~CastMediaNotificationProvider() = default; CastMediaNotificationProvider::~CastMediaNotificationProvider() = default;
base::WeakPtr<media_message_center::MediaNotificationItem>
CastMediaNotificationProvider::GetNotificationItem(const std::string& id) {
const auto item_it = items_.find(id);
if (item_it == items_.end())
return nullptr;
return item_it->second.GetWeakPtr();
}
std::set<std::string>
CastMediaNotificationProvider::GetActiveControllableNotificationIds() const {
std::set<std::string> ids;
for (const auto& item : items_) {
ids.insert(item.first);
}
return ids;
}
void CastMediaNotificationProvider::OnRoutesUpdated( void CastMediaNotificationProvider::OnRoutesUpdated(
const std::vector<media_router::MediaRoute>& routes, const std::vector<media_router::MediaRoute>& routes,
const std::vector<media_router::MediaRoute::Id>& joinable_route_ids) { const std::vector<media_router::MediaRoute::Id>& joinable_route_ids) {
...@@ -96,14 +113,6 @@ void CastMediaNotificationProvider::OnRoutesUpdated( ...@@ -96,14 +113,6 @@ void CastMediaNotificationProvider::OnRoutesUpdated(
items_changed_callback_.Run(); items_changed_callback_.Run();
} }
base::WeakPtr<media_message_center::MediaNotificationItem>
CastMediaNotificationProvider::GetNotificationItem(const std::string& id) {
const auto item_it = items_.find(id);
if (item_it == items_.end())
return nullptr;
return item_it->second.GetWeakPtr();
}
bool CastMediaNotificationProvider::HasItems() const { bool CastMediaNotificationProvider::HasItems() const {
return !items_.empty(); return !items_.empty();
} }
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include "base/callback_forward.h" #include "base/callback_forward.h"
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "chrome/browser/ui/global_media_controls/cast_media_notification_item.h" #include "chrome/browser/ui/global_media_controls/cast_media_notification_item.h"
#include "chrome/browser/ui/global_media_controls/media_notification_producer.h"
#include "components/media_router/browser/media_routes_observer.h" #include "components/media_router/browser/media_routes_observer.h"
class Profile; class Profile;
...@@ -22,7 +23,8 @@ class MediaNotificationController; ...@@ -22,7 +23,8 @@ class MediaNotificationController;
// Manages media notifications shown in the Global Media Controls dialog for // Manages media notifications shown in the Global Media Controls dialog for
// active Cast sessions. // active Cast sessions.
class CastMediaNotificationProvider : public media_router::MediaRoutesObserver { class CastMediaNotificationProvider : public MediaNotificationProducer,
public media_router::MediaRoutesObserver {
public: public:
CastMediaNotificationProvider( CastMediaNotificationProvider(
Profile* profile, Profile* profile,
...@@ -40,14 +42,16 @@ class CastMediaNotificationProvider : public media_router::MediaRoutesObserver { ...@@ -40,14 +42,16 @@ class CastMediaNotificationProvider : public media_router::MediaRoutesObserver {
const CastMediaNotificationProvider&) = delete; const CastMediaNotificationProvider&) = delete;
~CastMediaNotificationProvider() override; ~CastMediaNotificationProvider() override;
// MediaNotificationProducer:
base::WeakPtr<media_message_center::MediaNotificationItem>
GetNotificationItem(const std::string& id) override;
std::set<std::string> GetActiveControllableNotificationIds() const override;
// media_router::MediaRoutesObserver: // media_router::MediaRoutesObserver:
void OnRoutesUpdated(const std::vector<media_router::MediaRoute>& routes, void OnRoutesUpdated(const std::vector<media_router::MediaRoute>& routes,
const std::vector<media_router::MediaRoute::Id>& const std::vector<media_router::MediaRoute::Id>&
joinable_route_ids) override; joinable_route_ids) override;
base::WeakPtr<media_message_center::MediaNotificationItem>
GetNotificationItem(const std::string& id);
virtual bool HasItems() const; virtual bool HasItems() const;
size_t GetItemCount() const; size_t GetItemCount() const;
......
// Copyright 2021 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_UI_GLOBAL_MEDIA_CONTROLS_MEDIA_NOTIFICATION_PRODUCER_H_
#define CHROME_BROWSER_UI_GLOBAL_MEDIA_CONTROLS_MEDIA_NOTIFICATION_PRODUCER_H_
#include <set>
#include <string>
#include "base/memory/weak_ptr.h"
namespace media_message_center {
class MediaNotificationItem;
} // namespace media_message_center
// Creates and owns the media notification items shown in the Global Media
// Controls. There are multiple MediaNotificationProducers for different types
// of notification items.
class MediaNotificationProducer {
public:
virtual base::WeakPtr<media_message_center::MediaNotificationItem>
GetNotificationItem(const std::string& id) = 0;
virtual std::set<std::string> GetActiveControllableNotificationIds()
const = 0;
};
#endif // CHROME_BROWSER_UI_GLOBAL_MEDIA_CONTROLS_MEDIA_NOTIFICATION_PRODUCER_H_
...@@ -326,10 +326,13 @@ MediaNotificationService::MediaNotificationService(Profile* profile, ...@@ -326,10 +326,13 @@ MediaNotificationService::MediaNotificationService(Profile* profile,
base::BindRepeating( base::BindRepeating(
&MediaNotificationService::OnCastNotificationsChanged, &MediaNotificationService::OnCastNotificationsChanged,
base::Unretained(this))); base::Unretained(this)));
notification_providers_.insert(cast_notification_provider_.get());
} }
if (media_router::GlobalMediaControlsCastStartStopEnabled()) { if (media_router::GlobalMediaControlsCastStartStopEnabled()) {
presentation_request_notification_provider_ = presentation_request_notification_provider_ =
std::make_unique<PresentationRequestNotificationProvider>(this); std::make_unique<PresentationRequestNotificationProvider>(this);
notification_providers_.insert(
presentation_request_notification_provider_.get());
} }
} }
...@@ -693,17 +696,18 @@ void MediaNotificationService::SetDialogDelegate( ...@@ -693,17 +696,18 @@ void MediaNotificationService::SetDialogDelegate(
if (!dialog_delegate_) if (!dialog_delegate_)
return; return;
std::list<std::string> sorted_session_ids; auto notification_ids = GetActiveControllableNotificationIds();
for (const std::string& id : active_controllable_session_ids_) { std::list<std::string> sorted_notification_ids;
for (const std::string& id : notification_ids) {
auto session_it = sessions_.find(id); auto session_it = sessions_.find(id);
if (session_it != sessions_.end() && session_it->second.IsPlaying()) { if (session_it != sessions_.end() && session_it->second.IsPlaying()) {
sorted_session_ids.push_front(id); sorted_notification_ids.push_front(id);
} else { } else {
sorted_session_ids.push_back(id); sorted_notification_ids.push_back(id);
} }
} }
for (const std::string& id : sorted_session_ids) { for (const std::string& id : sorted_notification_ids) {
base::WeakPtr<media_message_center::MediaNotificationItem> item = base::WeakPtr<media_message_center::MediaNotificationItem> item =
GetNotificationItem(id); GetNotificationItem(id);
MediaNotificationContainerImpl* container = MediaNotificationContainerImpl* container =
...@@ -717,7 +721,7 @@ void MediaNotificationService::SetDialogDelegate( ...@@ -717,7 +721,7 @@ void MediaNotificationService::SetDialogDelegate(
} }
media_message_center::RecordConcurrentNotificationCount( media_message_center::RecordConcurrentNotificationCount(
active_controllable_session_ids_.size()); notification_ids.size());
if (cast_notification_provider_) { if (cast_notification_provider_) {
media_message_center::RecordConcurrentCastNotificationCount( media_message_center::RecordConcurrentCastNotificationCount(
...@@ -726,7 +730,7 @@ void MediaNotificationService::SetDialogDelegate( ...@@ -726,7 +730,7 @@ void MediaNotificationService::SetDialogDelegate(
} }
bool MediaNotificationService::HasActiveNotifications() const { bool MediaNotificationService::HasActiveNotifications() const {
return !active_controllable_session_ids_.empty(); return !GetActiveControllableNotificationIds().empty();
} }
bool MediaNotificationService::HasFrozenNotifications() const { bool MediaNotificationService::HasFrozenNotifications() const {
...@@ -854,20 +858,24 @@ MediaNotificationService::Session* MediaNotificationService::GetSession( ...@@ -854,20 +858,24 @@ MediaNotificationService::Session* MediaNotificationService::GetSession(
base::WeakPtr<media_message_center::MediaNotificationItem> base::WeakPtr<media_message_center::MediaNotificationItem>
MediaNotificationService::GetNonSessionNotificationItem(const std::string& id) { MediaNotificationService::GetNonSessionNotificationItem(const std::string& id) {
if (cast_notification_provider_) { for (auto* notification_provider : notification_providers_) {
auto item = cast_notification_provider_->GetNotificationItem(id); auto item = notification_provider->GetNotificationItem(id);
if (item) if (item) {
return item; return item;
}
} }
return nullptr;
}
if (presentation_request_notification_provider_) { std::set<std::string>
auto item = MediaNotificationService::GetActiveControllableNotificationIds() const {
presentation_request_notification_provider_->GetNotificationItem(id); std::set<std::string> ids = active_controllable_session_ids_;
if (item) for (auto* notification_provider : notification_providers_) {
return item; const std::set<std::string>& provider_ids =
notification_provider->GetActiveControllableNotificationIds();
ids.insert(provider_ids.begin(), provider_ids.end());
} }
return ids;
return nullptr;
} }
void MediaNotificationService::OnNotificationChanged( void MediaNotificationService::OnNotificationChanged(
......
...@@ -307,6 +307,8 @@ class MediaNotificationService ...@@ -307,6 +307,8 @@ class MediaNotificationService
base::WeakPtr<media_message_center::MediaNotificationItem> base::WeakPtr<media_message_center::MediaNotificationItem>
GetNonSessionNotificationItem(const std::string& id); GetNonSessionNotificationItem(const std::string& id);
std::set<std::string> GetActiveControllableNotificationIds() const;
// Called after changing anything about a notification to notify any observers // Called after changing anything about a notification to notify any observers
// and update the visibility of supplemental notifications. If the change is // and update the visibility of supplemental notifications. If the change is
// associated with a particular notification ID, that ID should be passed as // associated with a particular notification ID, that ID should be passed as
...@@ -321,23 +323,23 @@ class MediaNotificationService ...@@ -321,23 +323,23 @@ class MediaNotificationService
// Used to track whether there are any active controllable sessions. If not, // Used to track whether there are any active controllable sessions. If not,
// then there's nothing to show in the dialog and we can hide the toolbar // then there's nothing to show in the dialog and we can hide the toolbar
// icon. Contains sessions from both Media Session API and Cast. // icon. Contains sessions from the Media Session API.
std::unordered_set<std::string> active_controllable_session_ids_; std::set<std::string> active_controllable_session_ids_;
// Tracks the sessions that are currently frozen. If there are only frozen // Tracks the sessions that are currently frozen. If there are only frozen
// sessions, we will disable the toolbar icon and wait to hide it. // sessions, we will disable the toolbar icon and wait to hide it.
std::unordered_set<std::string> frozen_session_ids_; std::set<std::string> frozen_session_ids_;
// Tracks the sessions that are currently dragged out of the dialog. These // Tracks the sessions that are currently dragged out of the dialog. These
// should not be shown in the dialog and will be ignored for showing the // should not be shown in the dialog and will be ignored for showing the
// toolbar icon. // toolbar icon.
std::unordered_set<std::string> dragged_out_session_ids_; std::set<std::string> dragged_out_session_ids_;
// Tracks the sessions that are currently inactive. Sessions become inactive // Tracks the sessions that are currently inactive. Sessions become inactive
// after a period of time of being paused with no user interaction. Inactive // after a period of time of being paused with no user interaction. Inactive
// sessions are hidden from the dialog until the user interacts with them // sessions are hidden from the dialog until the user interacts with them
// again (e.g. by playing the session). // again (e.g. by playing the session).
std::unordered_set<std::string> inactive_session_ids_; std::set<std::string> inactive_session_ids_;
// A mapping of supplemental notification IDs to their associated web // A mapping of supplemental notification IDs to their associated web
// contents. See MediaNotificationController::AddSupplementalNotification for // contents. See MediaNotificationController::AddSupplementalNotification for
...@@ -366,6 +368,9 @@ class MediaNotificationService ...@@ -366,6 +368,9 @@ class MediaNotificationService
std::unique_ptr<PresentationRequestNotificationProvider> std::unique_ptr<PresentationRequestNotificationProvider>
presentation_request_notification_provider_; presentation_request_notification_provider_;
// Pointers to all notification providers owned by |this|.
std::set<MediaNotificationProducer*> notification_providers_;
base::ObserverList<MediaNotificationServiceObserver> observers_; base::ObserverList<MediaNotificationServiceObserver> observers_;
// Tracks the number of times we have recorded an action for a specific // Tracks the number of times we have recorded an action for a specific
......
...@@ -59,6 +59,12 @@ PresentationRequestNotificationProvider::GetNotificationItem( ...@@ -59,6 +59,12 @@ PresentationRequestNotificationProvider::GetNotificationItem(
return nullptr; return nullptr;
} }
std::set<std::string>
PresentationRequestNotificationProvider::GetActiveControllableNotificationIds()
const {
return item_ ? std::set<std::string>({item_->id()}) : std::set<std::string>();
}
void PresentationRequestNotificationProvider::OnStartPresentationContextCreated( void PresentationRequestNotificationProvider::OnStartPresentationContextCreated(
std::unique_ptr<media_router::StartPresentationContext> context) { std::unique_ptr<media_router::StartPresentationContext> context) {
DCHECK(context); DCHECK(context);
...@@ -69,9 +75,9 @@ void PresentationRequestNotificationProvider::OnStartPresentationContextCreated( ...@@ -69,9 +75,9 @@ void PresentationRequestNotificationProvider::OnStartPresentationContextCreated(
void PresentationRequestNotificationProvider::OnNotificationListChanged() {} void PresentationRequestNotificationProvider::OnNotificationListChanged() {}
void PresentationRequestNotificationProvider::OnMediaDialogOpened() { void PresentationRequestNotificationProvider::OnMediaDialogOpened() {
// At the point where this method is called, MediaNotificationService is in // At the point where this method is called, MediaNotificationService is
// a state where it can't accept new notifications. As a workaround, we // in a state where it can't accept new notifications. As a workaround,
// simply defer the handling of the event. // we simply defer the handling of the event.
content::GetUIThreadTaskRunner({})->PostTask( content::GetUIThreadTaskRunner({})->PostTask(
FROM_HERE, FROM_HERE,
base::BindOnce( base::BindOnce(
...@@ -92,17 +98,17 @@ void PresentationRequestNotificationProvider::OnMediaDialogClosed() { ...@@ -92,17 +98,17 @@ void PresentationRequestNotificationProvider::OnMediaDialogClosed() {
void PresentationRequestNotificationProvider::AfterMediaDialogOpened( void PresentationRequestNotificationProvider::AfterMediaDialogOpened(
base::WeakPtr<media_router::WebContentsPresentationManager> base::WeakPtr<media_router::WebContentsPresentationManager>
presentation_manager) { presentation_manager) {
// It's possible the presentation manager was deleted since the call to this // It's possible the presentation manager was deleted since the call to
// method was scheduled. // this method was scheduled.
if (!presentation_manager) if (!presentation_manager)
return; return;
presentation_manager->AddObserver(this); presentation_manager->AddObserver(this);
// Handle any request that was created while we weren't watching, first making // Handle any request that was created while we weren't watching, first
// sure the dialog hasn't been closed since the we found out it was opening. // making sure the dialog hasn't been closed since the we found out it was
// This is the normal way notifications are created for a default presentation // opening. This is the normal way notifications are created for a default
// request. // presentation request.
if (presentation_manager->HasDefaultPresentationRequest() && if (presentation_manager->HasDefaultPresentationRequest() &&
notification_service_->HasOpenDialog()) { notification_service_->HasOpenDialog()) {
OnDefaultPresentationChanged( OnDefaultPresentationChanged(
...@@ -121,10 +127,11 @@ void PresentationRequestNotificationProvider::AfterMediaDialogClosed( ...@@ -121,10 +127,11 @@ void PresentationRequestNotificationProvider::AfterMediaDialogClosed(
void PresentationRequestNotificationProvider::OnDefaultPresentationChanged( void PresentationRequestNotificationProvider::OnDefaultPresentationChanged(
const content::PresentationRequest* presentation_request) { const content::PresentationRequest* presentation_request) {
// NOTE: We only observe the presentation manager while the media control // NOTE: We only observe the presentation manager while the media control
// dialog is open, so this method is only handling the unusual case where the // dialog is open, so this method is only handling the unusual case where
// default presentation request is changed while the dialog is open. In the // the default presentation request is changed while the dialog is open.
// even more unusual case where the dialog is already open with a notification // In the even more unusual case where the dialog is already open with a
// for a non-default request, we ignored changes in the default request. // notification for a non-default request, we ignored changes in the
// default request.
if (!HasItemForNonDefaultRequest()) { if (!HasItemForNonDefaultRequest()) {
if (presentation_request) { if (presentation_request) {
CreateItemForPresentationRequest(*presentation_request, nullptr); CreateItemForPresentationRequest(*presentation_request, nullptr);
...@@ -137,8 +144,8 @@ void PresentationRequestNotificationProvider::OnDefaultPresentationChanged( ...@@ -137,8 +144,8 @@ void PresentationRequestNotificationProvider::OnDefaultPresentationChanged(
void PresentationRequestNotificationProvider::CreateItemForPresentationRequest( void PresentationRequestNotificationProvider::CreateItemForPresentationRequest(
const content::PresentationRequest& request, const content::PresentationRequest& request,
std::unique_ptr<media_router::StartPresentationContext> context) { std::unique_ptr<media_router::StartPresentationContext> context) {
// This may replace an existing item, which is the right thing to do if we've // This may replace an existing item, which is the right thing to do if
// reached this point. // we've reached this point.
item_.emplace(notification_service_, request, std::move(context)); item_.emplace(notification_service_, request, std::move(context));
auto* rfh = content::RenderFrameHost::FromID(request.render_frame_host_id); auto* rfh = content::RenderFrameHost::FromID(request.render_frame_host_id);
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "base/optional.h" #include "base/optional.h"
#include "chrome/browser/ui/global_media_controls/media_notification_producer.h"
#include "chrome/browser/ui/global_media_controls/media_notification_service_observer.h" #include "chrome/browser/ui/global_media_controls/media_notification_service_observer.h"
#include "chrome/browser/ui/global_media_controls/presentation_request_notification_item.h" #include "chrome/browser/ui/global_media_controls/presentation_request_notification_item.h"
#include "components/media_router/browser/presentation/web_contents_presentation_manager.h" #include "components/media_router/browser/presentation/web_contents_presentation_manager.h"
...@@ -39,7 +40,8 @@ ...@@ -39,7 +40,8 @@
// involved; at that point CastMediaNotificationProvider become responsible for // involved; at that point CastMediaNotificationProvider become responsible for
// managing the notification for an active session. // managing the notification for an active session.
class PresentationRequestNotificationProvider final class PresentationRequestNotificationProvider final
: public media_router::WebContentsPresentationManager::Observer, : public MediaNotificationProducer,
public media_router::WebContentsPresentationManager::Observer,
public MediaNotificationServiceObserver { public MediaNotificationServiceObserver {
public: public:
explicit PresentationRequestNotificationProvider( explicit PresentationRequestNotificationProvider(
...@@ -50,14 +52,16 @@ class PresentationRequestNotificationProvider final ...@@ -50,14 +52,16 @@ class PresentationRequestNotificationProvider final
const PresentationRequestNotificationProvider&) = delete; const PresentationRequestNotificationProvider&) = delete;
~PresentationRequestNotificationProvider() final; ~PresentationRequestNotificationProvider() final;
// MediaNotificationProducer:
base::WeakPtr<media_message_center::MediaNotificationItem> base::WeakPtr<media_message_center::MediaNotificationItem>
GetNotificationItem(const std::string& id); GetNotificationItem(const std::string& id) override;
std::set<std::string> GetActiveControllableNotificationIds() const override;
void OnStartPresentationContextCreated( void OnStartPresentationContextCreated(
std::unique_ptr<media_router::StartPresentationContext> context); std::unique_ptr<media_router::StartPresentationContext> context);
private: private:
// MediaNotificationServiceObserver // MediaNotificationServiceObserver:
void OnNotificationListChanged() final; void OnNotificationListChanged() final;
void OnMediaDialogOpened() final; void OnMediaDialogOpened() final;
void OnMediaDialogClosed() final; void OnMediaDialogClosed() final;
...@@ -69,7 +73,7 @@ class PresentationRequestNotificationProvider final ...@@ -69,7 +73,7 @@ class PresentationRequestNotificationProvider final
base::WeakPtr<media_router::WebContentsPresentationManager> base::WeakPtr<media_router::WebContentsPresentationManager>
presentation_manager); presentation_manager);
// WebContentsPresentationManager::Observer // WebContentsPresentationManager::Observer:
void OnDefaultPresentationChanged( void OnDefaultPresentationChanged(
const content::PresentationRequest* presentation_request) final; const content::PresentationRequest* presentation_request) final;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment