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
diff --git a/system/btif/avrcp/avrcp_service.cc b/system/btif/avrcp/avrcp_service.cc
index 8c22365..5a058f4 100644
--- a/system/btif/avrcp/avrcp_service.cc
+++ b/system/btif/avrcp/avrcp_service.cc
@@ -346,10 +346,11 @@
 
   // This function may be called on any thread, we need to make sure that the
   // device update happens on the main thread.
-  for (auto device : instance_->connection_handler_->GetListOfDevices()) {
-    do_in_bta_thread(FROM_HERE, base::Bind(&Device::SendMediaUpdate,
-                                           base::Unretained(device.get()),
-                                           track_changed, play_state, queue));
+  for (const auto& device :
+       instance_->connection_handler_->GetListOfDevices()) {
+    do_in_bta_thread(FROM_HERE,
+                     base::Bind(&Device::SendMediaUpdate, device.get()->Get(),
+                                track_changed, play_state, queue));
   }
 }
 
@@ -361,11 +362,11 @@
             << " uids=" << uids;
 
   // Ensure that the update is posted to the correct thread
-  for (auto device : instance_->connection_handler_->GetListOfDevices()) {
-    do_in_bta_thread(
-        FROM_HERE,
-        base::Bind(&Device::SendFolderUpdate, base::Unretained(device.get()),
-                   available_players, addressed_players, uids));
+  for (const auto& device :
+       instance_->connection_handler_->GetListOfDevices()) {
+    do_in_bta_thread(FROM_HERE,
+                     base::Bind(&Device::SendFolderUpdate, device.get()->Get(),
+                                available_players, addressed_players, uids));
   }
 }
 
diff --git a/system/profile/avrcp/device.cc b/system/profile/avrcp/device.cc
index 9b25fac..7f8ecae 100644
--- a/system/profile/avrcp/device.cc
+++ b/system/profile/avrcp/device.cc
@@ -52,6 +52,8 @@
   volume_interface_ = volume_interface;
 }
 
+base::WeakPtr<Device> Device::Get() { return weak_ptr_factory_.GetWeakPtr(); }
+
 bool Device::IsActive() const {
   return address_ == a2dp_interface_->active_peer();
 }
diff --git a/system/profile/avrcp/device.h b/system/profile/avrcp/device.h
index 5ef886d..b1f3420 100644
--- a/system/profile/avrcp/device.h
+++ b/system/profile/avrcp/device.h
@@ -55,6 +55,12 @@
       uint16_t ctrl_mtu, uint16_t browse_mtu);
   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_; };
 
   /**