patchpanel-client: Add device changed signal handling

BUG=b:174432555
TEST=dbus-monitor --system \
"type=signal,interface='org.chromium.PatchPanel'"
and then log in and see 2 signals corresponding to arc_eth0 and
arc_wlan0 being added; then unplug eth0 and see signal corresponding to
removal, then plug back in and see that signal.

Change-Id: I5ab9a979a15c35cc96e8cc5ccb38e64bf62562b7
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform2/+/2566855
Tested-by: Garrick Evans <garrick@chromium.org>
Commit-Queue: Garrick Evans <garrick@chromium.org>
Reviewed-by: Hugo Benichi <hugobenichi@google.com>
diff --git a/patchpanel/dbus/client.cc b/patchpanel/dbus/client.cc
index 66a9a43..b3c8cea 100644
--- a/patchpanel/dbus/client.cc
+++ b/patchpanel/dbus/client.cc
@@ -65,6 +65,19 @@
       {response.counters().begin(), response.counters().end()});
 }
 
+void OnNetworkDeviceChangedSignal(
+    const Client::NetworkDeviceChangedSignalHandler& handler,
+    dbus::Signal* signal) {
+  dbus::MessageReader reader(signal);
+  NetworkDeviceChangedSignal proto;
+  if (!reader.PopArrayOfBytesAsProto(&proto)) {
+    LOG(ERROR) << "Failed to parse NetworkDeviceChangedSignal proto";
+    return;
+  }
+
+  handler.Run(proto);
+}
+
 void OnNeighborReachabilityEventSignal(
     const Client::NeighborReachabilityEventHandler& handler,
     dbus::Signal* signal) {
@@ -135,6 +148,9 @@
 
   std::vector<NetworkDevice> GetDevices() override;
 
+  void RegisterNetworkDeviceChangedSignalHandler(
+      NetworkDeviceChangedSignalHandler handler) override;
+
   void RegisterNeighborReachabilityEventHandler(
       NeighborReachabilityEventHandler handler) override;
 
@@ -620,6 +636,14 @@
   return devices;
 }
 
+void ClientImpl::RegisterNetworkDeviceChangedSignalHandler(
+    NetworkDeviceChangedSignalHandler handler) {
+  proxy_->ConnectToSignal(
+      kPatchPanelInterface, kNetworkDeviceChangedSignal,
+      base::BindRepeating(OnNetworkDeviceChangedSignal, handler),
+      base::BindOnce(OnSignalConnectedCallback));
+}
+
 void ClientImpl::RegisterNeighborReachabilityEventHandler(
     NeighborReachabilityEventHandler handler) {
   proxy_->ConnectToSignal(