This allows us to print better warning strings, and in the future
would allow us to profile each operation in a meaningful way.
Also, add context to some of the progress steps as required.
This allows creating the silo when starting the engine with custom
plugin keys such as WacomI2cFlashBaseAddr.
If we move the plugin initialization earlier then we don't get the
HwID matches, so we really do have to split this into a 4-stage startup,
e.g. ->load(), ->init(), ->startup() and ->coldplug().
Provide a device instance builder that allows plugins to easily
create multiple instance IDs based on parent attributes.
Also fix a lot of the instance ID orders, so that we add more generic
IDs first, and more specific IDs after.
tristate features will automatically disable if dependencies marked
as required are missing.
Packagers can manually override using `auto_features`.
Link: https://mesonbuild.com/Build-options.html#features
We were calling g_module_symbol() 2703 times, which is actually more
expensive than you'd think.
It also means the plugins are actually what we tell people they are:
A set of vfuncs that get run. The reality before that they were dlsym'd
functions that get called at pretty random times.
Now two plugins are using hardcoded SPI constants for various CFI chips,
and it makes sense to have some common quirk data that can be used by
both.
Add a FuSpiChip helper object that can be used by FuDevice subclasses
to get the specific SPI commands to use for each flash ID.
Quite a few plugins are using a FuDeviceLocker to detach then attach in
the error path, and finding them isn't easy as we explicitly cast to a
FuDeviceLockerFunc.
For sanity, just provide both symbols so we can do the right thing in
both cases. It seems like a sensible thing to allow.
Fixes https://github.com/fwupd/fwupd/issues/3771
It's actually quite hard to build a front-end for fwupd at the moment
as you're never sure when the progress bar is going to zip back to 0%
and start all over again. Some plugins go 0..100% for write, others
go 0..100% for erase, then again for write, then *again* for verify.
By creating a helper object we can easily split up the progress of the
specific task, e.g. write_firmware().
We can encode at the plugin level "the erase takes 50% of the time, the
write takes 40% and the read takes 10%". This means we can have a
progressbar which goes up just once at a consistent speed.
The benefit of using the proxy device is that we can 'use' the proxy
device for device access, but 'report' the progress on the passed
FuDevice instance.
This means the front-end reports the device status correctly when
updating composite devices that us proxies.
The comment always said we should move it to the daemon if another
plugin started doing this, and that is now.
I assume at some point we forgot to remove it when converting an object
from FINAL to DERIVABLE and the anti-pattern just got copied around the
codebase...
The CustomFlags feature is a bit of a hack where we just join the flags
and store in the device metadata section as a string. This makes it
inefficient to check if just one flag exists as we have to split the
string to a temporary array each time.
Rather than adding to the hack by splitting, appending (if not exists)
then joining again, store the flags in the plugin privdata directly.
This allows us to support negating custom properties (e.g. ~hint) and
also allows quirks to append custom values without duplicating them on
each GUID match, e.g.
[USB\VID_17EF&PID_307F]
Plugin = customflag1
[USB\VID_17EF&PID_307F&HUB_0002]
Flags = customflag2
...would result in customflag1,customflag2 which is the same as you'd
get from an enumerated device flag doing the same thing.
Add a FuDevice->ready() vfunc that is run after ->setup()
This allows plugins to perform setup actions that require quirk matches
after the instance IDs have been converted. This allows us to also
remove FuVliDevice->setup() as the ordering chain has been broken.
There are two USB-3 hubs internally (with the same VID&PID), and the
MSP430 is only attached to the top-level one.
Fixes https://github.com/fwupd/fwupd/issues/3366
Before this change calling FuUsbDevice->open() opened the device, and
also unconditionally added various GUIDs and InstanceIDs which we
normally do in setup.
Then fu_device_setup() would call the FuSubclass->setup() vfunc which
would have no way of either opting out of the FuUsbDevice->setup()-like
behaviour, or controlling if the parent class ->setup is run before or
after the subclass setup.
Split up FuUsbDevice->open() into clear ->open() and ->setup() phases
and add the parent class calls where appropriate.
This means that ->setup() now behaves the same as all the other vfuncs.