If the device parent is added using fu_device_add_parent_guid() or ParentGuid
from a quirk file then the child is not returned in fu_device_get_children() by
design as the physical ID will be likely different.
This means we cannot reliably 'depsolve' the order in FuDevice as we need the
full list of devices that might be parents. The existing algorithm had several
logical problems when dealing with more than a single parent and child.
The FuDeviceList object is the right place to do this as it knows about all
added devices on the system.
This means the addition of a logical device causes the root logical device
(and all it's children, and grandchildren) to be re-ordered. This allows
firmware on deeply nested composite devices like hubs to be installed in the
correct order.
It wasn't hugely clear what the platform ID was actually meant to represent. In
some cases it was being used like a physical ID, in others it was a logical ID,
and in others it was both. In some cases it was even used as a sysfs path.
Clear up all the confusion by splitting the platform ID into two parts, an
optional *physical* ID to represent the electrical connection, and an optional
*logical* ID to disambiguate composite devices with the same physical ID.
Also create an explicit sysfs_path getter for FuUdevDevice to make this clear.
This allows WAIT_FOR_REPLUG to always work, rather than depending on the order
that the GUIDs were added, and that the kernel would always return the same
sysfs path (which it doesn't have to do, especially for hidraw devices).
This ensures we get progress events when replugging a device. Also, remove the
callbacks on the 'old' device to avoid causing multiple events on a 2nd-replug.
When changing from runtime->bootloader->runtime the usual way of handling this
in a fwupd plugin is to:
* reset the device and wait for a replug
* flash the hardware
* reset the device and wait for a replug
This works well when the runtime and bootloader modes are handled by the same
plugin. For situations like the Nitrokey device, where one plugin handles the
runtime (nitrokey), and another handles the bootloader (dfu) we have to have
the ability to 'ignore' the device removal and just issue a 'changed' signal
so the client refreshes the properties.
This moves more functionality out of the engine, and will allow us to add some
cleverness to the device list to allow the FuDevice to be shared between
different plugins.