Commit 257b682a authored by Ted Meyer's avatar Ted Meyer Committed by Commit Bot

Send a notice that the video player is destroyed to MediaLog

This happens synchronously with the destruction of WebMediaPlayerImpl
so that the devtools backend for MediaLog knows it shouldn't be sending
events since the page may have been destroyed. Events that happen
after WEBMEDIAPLAYER_DESTROYED get dropped from _only_ the devtools
version.

This should fix the nullptr deref bug caused by the destruction order
of the blink objects and the WebMediaPlayerImpl::DestructionHelper.

Bug: 794255
Bug: 1014433
Change-Id: I25e2110a31561367baf7104c77a8e5301b5afb0c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1891078
Commit-Queue: Ted Meyer <tmathmeyer@chromium.org>
Reviewed-by: default avatarDale Curtis <dalecurtis@chromium.org>
Cr-Commit-Position: refs/heads/master@{#711858}
parent fa5dfa61
...@@ -65,6 +65,10 @@ BatchingMediaLog::~BatchingMediaLog() { ...@@ -65,6 +65,10 @@ BatchingMediaLog::~BatchingMediaLog() {
SendQueuedMediaEvents(); SendQueuedMediaEvents();
} }
void BatchingMediaLog::OnWebMediaPlayerDestroyedLocked() {
event_handler_->OnWebMediaPlayerDestroyed();
}
void BatchingMediaLog::AddEventLocked( void BatchingMediaLog::AddEventLocked(
std::unique_ptr<media::MediaLogEvent> event) { std::unique_ptr<media::MediaLogEvent> event) {
Log(event.get()); Log(event.get());
......
...@@ -35,6 +35,7 @@ class CONTENT_EXPORT BatchingMediaLog : public media::MediaLog { ...@@ -35,6 +35,7 @@ class CONTENT_EXPORT BatchingMediaLog : public media::MediaLog {
public: public:
virtual ~EventHandler() = default; virtual ~EventHandler() = default;
virtual void SendQueuedMediaEvents(std::vector<media::MediaLogEvent>) = 0; virtual void SendQueuedMediaEvents(std::vector<media::MediaLogEvent>) = 0;
virtual void OnWebMediaPlayerDestroyed() = 0;
}; };
BatchingMediaLog(const GURL& security_origin, BatchingMediaLog(const GURL& security_origin,
...@@ -48,6 +49,7 @@ class CONTENT_EXPORT BatchingMediaLog : public media::MediaLog { ...@@ -48,6 +49,7 @@ class CONTENT_EXPORT BatchingMediaLog : public media::MediaLog {
protected: protected:
// MediaLog implementation. // MediaLog implementation.
void AddEventLocked(std::unique_ptr<media::MediaLogEvent> event) override; void AddEventLocked(std::unique_ptr<media::MediaLogEvent> event) override;
void OnWebMediaPlayerDestroyedLocked() override;
std::string GetErrorMessageLocked() override; std::string GetErrorMessageLocked() override;
private: private:
......
...@@ -22,6 +22,7 @@ class TestEventHandler : public BatchingMediaLog::EventHandler { ...@@ -22,6 +22,7 @@ class TestEventHandler : public BatchingMediaLog::EventHandler {
explicit TestEventHandler(BatchingMediaLogTest* test_cls) explicit TestEventHandler(BatchingMediaLogTest* test_cls)
: test_cls_(test_cls) {} : test_cls_(test_cls) {}
void SendQueuedMediaEvents(std::vector<media::MediaLogEvent> events) override; void SendQueuedMediaEvents(std::vector<media::MediaLogEvent> events) override;
void OnWebMediaPlayerDestroyed() override;
private: private:
BatchingMediaLogTest* test_cls_; BatchingMediaLogTest* test_cls_;
...@@ -79,6 +80,8 @@ void TestEventHandler::SendQueuedMediaEvents( ...@@ -79,6 +80,8 @@ void TestEventHandler::SendQueuedMediaEvents(
test_cls_->AddEventsForTesting(events); test_cls_->AddEventsForTesting(events);
} }
void TestEventHandler::OnWebMediaPlayerDestroyed() {}
TEST_F(BatchingMediaLogTest, ThrottleSendingEvents) { TEST_F(BatchingMediaLogTest, ThrottleSendingEvents) {
AddEvent(media::MediaLogEvent::LOAD); AddEvent(media::MediaLogEvent::LOAD);
EXPECT_EQ(0, message_count()); EXPECT_EQ(0, message_count());
......
...@@ -34,6 +34,10 @@ InspectorMediaEventHandler::InspectorMediaEventHandler( ...@@ -34,6 +34,10 @@ InspectorMediaEventHandler::InspectorMediaEventHandler(
// this method is no longer needed. Refactor MediaLogEvent at some point. // this method is no longer needed. Refactor MediaLogEvent at some point.
void InspectorMediaEventHandler::SendQueuedMediaEvents( void InspectorMediaEventHandler::SendQueuedMediaEvents(
std::vector<media::MediaLogEvent> events_to_send) { std::vector<media::MediaLogEvent> events_to_send) {
// If the video player is gone, the whole frame
if (video_player_destroyed_)
return;
blink::InspectorPlayerEvents events; blink::InspectorPlayerEvents events;
blink::InspectorPlayerProperties properties; blink::InspectorPlayerProperties properties;
...@@ -77,4 +81,8 @@ void InspectorMediaEventHandler::SendQueuedMediaEvents( ...@@ -77,4 +81,8 @@ void InspectorMediaEventHandler::SendQueuedMediaEvents(
inspector_context_->SetPlayerProperties(player_id_, properties); inspector_context_->SetPlayerProperties(player_id_, properties);
} }
void InspectorMediaEventHandler::OnWebMediaPlayerDestroyed() {
video_player_destroyed_ = true;
}
} // namespace content } // namespace content
...@@ -21,10 +21,12 @@ class CONTENT_EXPORT InspectorMediaEventHandler ...@@ -21,10 +21,12 @@ class CONTENT_EXPORT InspectorMediaEventHandler
explicit InspectorMediaEventHandler(blink::MediaInspectorContext*); explicit InspectorMediaEventHandler(blink::MediaInspectorContext*);
~InspectorMediaEventHandler() override = default; ~InspectorMediaEventHandler() override = default;
void SendQueuedMediaEvents(std::vector<media::MediaLogEvent>) override; void SendQueuedMediaEvents(std::vector<media::MediaLogEvent>) override;
void OnWebMediaPlayerDestroyed() override;
private: private:
blink::MediaInspectorContext* inspector_context_; blink::MediaInspectorContext* inspector_context_;
blink::WebString player_id_; blink::WebString player_id_;
bool video_player_destroyed_ = false;
}; };
} // namespace content } // namespace content
......
...@@ -13,4 +13,8 @@ void RenderMediaEventHandler::SendQueuedMediaEvents( ...@@ -13,4 +13,8 @@ void RenderMediaEventHandler::SendQueuedMediaEvents(
RenderThread::Get()->Send(new ViewHostMsg_MediaLogEvents(events_to_send)); RenderThread::Get()->Send(new ViewHostMsg_MediaLogEvents(events_to_send));
} }
// This media log doesn't care, since the RenderThread outlives us for
// chrome://media-internals.
void RenderMediaEventHandler::OnWebMediaPlayerDestroyed() {}
} // namespace content } // namespace content
...@@ -19,6 +19,7 @@ class CONTENT_EXPORT RenderMediaEventHandler ...@@ -19,6 +19,7 @@ class CONTENT_EXPORT RenderMediaEventHandler
RenderMediaEventHandler() = default; RenderMediaEventHandler() = default;
~RenderMediaEventHandler() override = default; ~RenderMediaEventHandler() override = default;
void SendQueuedMediaEvents(std::vector<media::MediaLogEvent>) override; void SendQueuedMediaEvents(std::vector<media::MediaLogEvent>) override;
void OnWebMediaPlayerDestroyed() override;
}; };
} // namespace content } // namespace content
......
...@@ -173,6 +173,16 @@ MediaLog::~MediaLog() { ...@@ -173,6 +173,16 @@ MediaLog::~MediaLog() {
InvalidateLog(); InvalidateLog();
} }
void MediaLog::OnWebMediaPlayerDestroyed() {
AddEvent(CreateEvent(MediaLogEvent::WEBMEDIAPLAYER_DESTROYED));
base::AutoLock auto_lock(parent_log_record_->lock);
// Forward to the parent log's implementation.
if (parent_log_record_->media_log)
parent_log_record_->media_log->OnWebMediaPlayerDestroyedLocked();
}
void MediaLog::OnWebMediaPlayerDestroyedLocked() {}
void MediaLog::AddEvent(std::unique_ptr<MediaLogEvent> event) { void MediaLog::AddEvent(std::unique_ptr<MediaLogEvent> event) {
base::AutoLock auto_lock(parent_log_record_->lock); base::AutoLock auto_lock(parent_log_record_->lock);
// Forward to the parent log's implementation. // Forward to the parent log's implementation.
......
...@@ -79,6 +79,10 @@ class MEDIA_EXPORT MediaLog { ...@@ -79,6 +79,10 @@ class MEDIA_EXPORT MediaLog {
// do something. // do something.
void AddEvent(std::unique_ptr<MediaLogEvent> event); void AddEvent(std::unique_ptr<MediaLogEvent> event);
// Notify the media log that the player is destroyed. Some implementations
// will want to change event handling based on this.
void OnWebMediaPlayerDestroyed();
// Returns a string usable as the contents of a MediaError.message. // Returns a string usable as the contents of a MediaError.message.
// This method returns an incomplete message if it is called before the // This method returns an incomplete message if it is called before the
// pertinent events for the error have been added to the log. // pertinent events for the error have been added to the log.
...@@ -143,6 +147,7 @@ class MEDIA_EXPORT MediaLog { ...@@ -143,6 +147,7 @@ class MEDIA_EXPORT MediaLog {
// //
// Please see the documentation for the corresponding public methods. // Please see the documentation for the corresponding public methods.
virtual void AddEventLocked(std::unique_ptr<MediaLogEvent> event); virtual void AddEventLocked(std::unique_ptr<MediaLogEvent> event);
virtual void OnWebMediaPlayerDestroyedLocked();
virtual std::string GetErrorMessageLocked(); virtual std::string GetErrorMessageLocked();
// Notify all child logs that they should stop working. This should be called // Notify all child logs that they should stop working. This should be called
......
...@@ -457,8 +457,7 @@ WebMediaPlayerImpl::~WebMediaPlayerImpl() { ...@@ -457,8 +457,7 @@ WebMediaPlayerImpl::~WebMediaPlayerImpl() {
video_layer_->StopUsingProvider(); video_layer_->StopUsingProvider();
simple_watch_timer_.Stop(); simple_watch_timer_.Stop();
media_log_->AddEvent( media_log_->OnWebMediaPlayerDestroyed();
media_log_->CreateEvent(MediaLogEvent::WEBMEDIAPLAYER_DESTROYED));
if (data_source_) if (data_source_)
data_source_->Stop(); data_source_->Stop();
......
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