Tentative fix for a mirroring shutdown crash on cast linux receivers.

This also requires a change in chromium/src.

Bug: b:374199735
Change-Id: I76bc61259d939ff8c87aba84650f228de92c5c2e
Reviewed-on: https://chromium-review.googlesource.com/c/openscreen/+/6533602
Reviewed-by: Jordan Bayles <jophba@chromium.org>
Reviewed-by: Mark Foltz <mfoltz@chromium.org>
Commit-Queue: Antonio Rivera <antoniori@google.com>
diff --git a/cast/streaming/public/receiver_session.cc b/cast/streaming/public/receiver_session.cc
index c1fcec9..7d891da 100644
--- a/cast/streaming/public/receiver_session.cc
+++ b/cast/streaming/public/receiver_session.cc
@@ -86,12 +86,13 @@
       environment_(environment),
       constraints_(std::move(constraints)),
       session_id_(MakeUniqueSessionId("streaming_receiver")),
-      messenger_(message_port,
-                 session_id_,
-                 [this](Error error) {
-                   OSP_DLOG_WARN << "Got a session messenger error: " << error;
-                   client_.OnError(this, error);
-                 }),
+      messenger_(std::make_unique<ReceiverSessionMessenger>(
+          message_port,
+          session_id_,
+          [this](Error error) {
+            OSP_DLOG_WARN << "Got a session messenger error: " << error;
+            client_.OnError(this, error);
+          })),
       packet_router_(environment_) {
   OSP_CHECK(std::none_of(
       constraints_.video_codecs.begin(), constraints_.video_codecs.end(),
@@ -100,17 +101,17 @@
       constraints_.audio_codecs.begin(), constraints_.audio_codecs.end(),
       [](AudioCodec c) { return c == AudioCodec::kNotSpecified; }));
 
-  messenger_.SetHandler(
+  messenger_->SetHandler(
       SenderMessage::Type::kOffer,
       [this](const std::string& sender_id, SenderMessage message) {
         OnOffer(sender_id, std::move(message));
       });
-  messenger_.SetHandler(
+  messenger_->SetHandler(
       SenderMessage::Type::kGetCapabilities,
       [this](const std::string& sender_id, SenderMessage message) {
         OnCapabilitiesRequest(sender_id, std::move(message));
       });
-  messenger_.SetHandler(
+  messenger_->SetHandler(
       SenderMessage::Type::kRpc,
       [this](const std::string& sender_id, SenderMessage message) {
         this->OnRpcMessage(sender_id, std::move(message));
@@ -119,6 +120,10 @@
 }
 
 ReceiverSession::~ReceiverSession() {
+  // messenger_ must be destroyed before OnReceiversDestroying runs, since it
+  // calls message_port_.ResetClient(). That MessagePort is destroyed before
+  // OnReceiversDestroying returns. See crbug.com/374199735 for more details.
+  messenger_.reset();
   ResetReceivers(Client::kEndOfSession);
 }
 
@@ -245,7 +250,7 @@
 
   // NOTE: we respond to any arbitrary sender here, to allow sender to get
   // capabilities before making an OFFER.
-  const Error result = messenger_.SendMessage(sender_id, std::move(response));
+  const Error result = messenger_->SendMessage(sender_id, std::move(response));
   if (!result.ok()) {
     client_.OnError(this, result);
   }
@@ -280,7 +285,7 @@
     return;
   }
 
-  const Error error = messenger_.SendMessage(
+  const Error error = messenger_->SendMessage(
       negotiated_sender_id_,
       ReceiverMessage{ReceiverMessage::Type::kRpc, -1, true /* valid */,
                       std::move(message)});
@@ -340,7 +345,7 @@
         this, RemotingNegotiation{std::move(receivers), rpc_messenger_.get()});
   }
 
-  const Error result = messenger_.SendMessage(
+  const Error result = messenger_->SendMessage(
       negotiated_sender_id_,
       ReceiverMessage{ReceiverMessage::Type::kAnswer,
                       properties.sequence_number, true /* valid */,
@@ -496,7 +501,7 @@
                                            int sequence_number,
                                            const Error& error) {
   OSP_DLOG_WARN << error;
-  const Error result = messenger_.SendMessage(
+  const Error result = messenger_->SendMessage(
       sender_id,
       ReceiverMessage{ReceiverMessage::Type::kAnswer, sequence_number,
                       false /* valid */, ReceiverError(error)});
diff --git a/cast/streaming/public/receiver_session.h b/cast/streaming/public/receiver_session.h
index 5df8a21..fe6e02f 100644
--- a/cast/streaming/public/receiver_session.h
+++ b/cast/streaming/public/receiver_session.h
@@ -228,7 +228,7 @@
   std::string negotiated_sender_id_;
 
   // The session messenger used for the lifetime of this session.
-  ReceiverSessionMessenger messenger_;
+  std::unique_ptr<ReceiverSessionMessenger> messenger_;
 
   // The packet router to be used for all Receivers spawned by this session.
   ReceiverPacketRouter packet_router_;