Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit aa5490d4 authored by Ajay Panicker's avatar Ajay Panicker
Browse files

DO NOT MERGE: Use a weak pointer to deliver updates to AVRCP devices.

If a device disconnects right before a update message gets queued, the
device becomes null and there is a crash when the callback for the
update executes on the disconnected device. This patch switches the
device reference from being Unretained to using a weak pointer so that
the callback just doesn't execute if the device is disconnected.

Bug: 120431125
Bug: 120445479
Test: Use the same test as b/120477414 as that bug causes a disconnect
at the same time as a media update.

Change-Id: I1dcc08e5c9866106e7ec0dad52505e34b42da600
parent 60a63513
Loading
Loading
Loading
Loading
+10 −9
Original line number Original line Diff line number Diff line
@@ -346,9 +346,10 @@ void AvrcpService::SendMediaUpdate(bool track_changed, bool play_state,


  // This function may be called on any thread, we need to make sure that the
  // This function may be called on any thread, we need to make sure that the
  // device update happens on the main thread.
  // device update happens on the main thread.
  for (auto device : instance_->connection_handler_->GetListOfDevices()) {
  for (const auto& device :
    do_in_bta_thread(FROM_HERE, base::Bind(&Device::SendMediaUpdate,
       instance_->connection_handler_->GetListOfDevices()) {
                                           base::Unretained(device.get()),
    do_in_bta_thread(FROM_HERE,
                     base::Bind(&Device::SendMediaUpdate, device.get()->Get(),
                                track_changed, play_state, queue));
                                track_changed, play_state, queue));
  }
  }
}
}
@@ -361,10 +362,10 @@ void AvrcpService::SendFolderUpdate(bool available_players,
            << " uids=" << uids;
            << " uids=" << uids;


  // Ensure that the update is posted to the correct thread
  // Ensure that the update is posted to the correct thread
  for (auto device : instance_->connection_handler_->GetListOfDevices()) {
  for (const auto& device :
    do_in_bta_thread(
       instance_->connection_handler_->GetListOfDevices()) {
        FROM_HERE,
    do_in_bta_thread(FROM_HERE,
        base::Bind(&Device::SendFolderUpdate, base::Unretained(device.get()),
                     base::Bind(&Device::SendFolderUpdate, device.get()->Get(),
                                available_players, addressed_players, uids));
                                available_players, addressed_players, uids));
  }
  }
}
}
+2 −0
Original line number Original line Diff line number Diff line
@@ -52,6 +52,8 @@ void Device::RegisterInterfaces(MediaInterface* media_interface,
  volume_interface_ = volume_interface;
  volume_interface_ = volume_interface;
}
}


base::WeakPtr<Device> Device::Get() { return weak_ptr_factory_.GetWeakPtr(); }

bool Device::IsActive() const {
bool Device::IsActive() const {
  return address_ == a2dp_interface_->active_peer();
  return address_ == a2dp_interface_->active_peer();
}
}
+6 −0
Original line number Original line Diff line number Diff line
@@ -55,6 +55,12 @@ class Device {
      uint16_t ctrl_mtu, uint16_t browse_mtu);
      uint16_t ctrl_mtu, uint16_t browse_mtu);
  virtual ~Device() = default;
  virtual ~Device() = default;


  /**
   * Gets a weak pointer to this device that is invalidated when the device is
   * disconnected.
   */
  base::WeakPtr<Device> Get();

  const RawAddress& GetAddress() const { return address_; };
  const RawAddress& GetAddress() const { return address_; };


  /**
  /**