This allows us to override the location we load data files from, which
allows us to do more kinds of installed tests in the future.
Also, move the global data/tests content into the place that it is used
as it was getting impossible to manage.
Note that g_assert() should not be used in unit tests, since it is a
no-op when compiling with G_DISABLE_ASSERT. Use g_assert() in production
code, and g_assert_true() in unit tests.
See https://github.com/fwupd/fwupd/issues/3790
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.
Some Poly usb devices report zero in the bwPollTimeout field of
GET_STATUS request. The host can issue the next DFU_DNLOAD
request immediately without any delay.
Introduced a private flag to skip the default DNLOAD timeout
(5ms) fix. It could remarkably reduce the firmware downloading
time taking into account the large firmware (more than 500MB).
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.
This will improve the pre-commit hook coverage.
For dfu: waive pre-commit checks for internal header file
This is internal to the plugin not to the library.
Until gi-docgen is declared stable support either of them.
This effectively means that hand builds and CI builds will use
gi-docgen, but distro builds use gtk-doc-tools.
fu_dfu_tool_get_default_device returns a newly create FuDfuDevice
'device'; but since it is marked as g_autoptr, it is destroyed when
leaving the scope and the caller receives garbage.
So steal the pointer before leaving the scope.
,----
| ==697985== Invalid read of size 8
| ==697985== at 0x4B50F49: g_type_check_instance_is_fundamentally_a (gtype.c:4080)
| ==697985== by 0x4B3A988: g_object_unref (gobject.c:3421)
| ==697985== by 0x406CF3: glib_autoptr_clear_GObject (gobject-autocleanups.h:27)
| ==697985== by 0x406DD5: glib_autoptr_clear_FwupdDevice (gusb-autocleanups.h:17)
| ==697985== by 0x406E9C: glib_autoptr_clear_FuDevice (fu-device.h:18)
| ==697985== by 0x406EE3: glib_autoptr_clear_FuUsbDevice (fu-usb-device.h:22)
| ==697985== by 0x406F6A: glib_autoptr_clear_FuDfuDevice (fu-dfu-device.h:19)
| ==697985== by 0x406F88: glib_autoptr_cleanup_FuDfuDevice (fu-dfu-device.h:19)
| ==697985== by 0x40898D: fu_dfu_tool_read (fu-dfu-tool.c:577)
| ==697985== by 0x407518: fu_dfu_tool_run (fu-dfu-tool.c:162)
| ==697985== by 0x4097E0: main (fu-dfu-tool.c:959)
| ==697985== Address 0x67fbfe0 is 640 bytes inside a block of size 672 free'd
| ==697985== at 0x48430E4: free (vg_replace_malloc.c:755)
| ==697985== by 0x4BD124C: g_free (gmem.c:199)
| ==697985== by 0x4BEB76F: g_slice_free1 (gslice.c:1180)
| ==697985== by 0x4B4FDBB: g_type_free_instance (gtype.c:1993)
| ==697985== by 0x406CF3: glib_autoptr_clear_GObject (gobject-autocleanups.h:27)
| ==697985== by 0x406DD5: glib_autoptr_clear_FwupdDevice (gusb-autocleanups.h:17)
| ==697985== by 0x406E9C: glib_autoptr_clear_FuDevice (fu-device.h:18)
| ==697985== by 0x406EE3: glib_autoptr_clear_FuUsbDevice (fu-usb-device.h:22)
| ==697985== by 0x406F6A: glib_autoptr_clear_FuDfuDevice (fu-dfu-device.h:19)
| ==697985== by 0x406F88: glib_autoptr_cleanup_FuDfuDevice (fu-dfu-device.h:19)
| ==697985== by 0x407762: fu_dfu_tool_get_default_device (fu-dfu-tool.c:191)
| ==697985== by 0x408736: fu_dfu_tool_read (fu-dfu-tool.c:592)
| ==697985== Block was alloc'd at
| ==697985== at 0x484086F: malloc (vg_replace_malloc.c:380)
| ==697985== by 0x4BD4938: g_malloc (gmem.c:106)
| ==697985== by 0x4BEC1F4: g_slice_alloc (gslice.c:1069)
| ==697985== by 0x4BEC85D: g_slice_alloc0 (gslice.c:1095)
| ==697985== by 0x4B5511A: g_type_create_instance (gtype.c:1893)
| ==697985== by 0x4B3CB8C: g_object_new_internal (gobject.c:1939)
| ==697985== by 0x4B3E107: g_object_new_valist (gobject.c:2282)
| ==697985== by 0x4B3E63C: g_object_new (gobject.c:1782)
| ==697985== by 0x40B0CF: fu_dfu_device_new (fu-dfu-device.c:571)
| ==697985== by 0x407723: fu_dfu_tool_get_default_device (fu-dfu-tool.c:230)
| ==697985== by 0x408736: fu_dfu_tool_read (fu-dfu-tool.c:592)
| ==697985== by 0x407518: fu_dfu_tool_run (fu-dfu-tool.c:162)
`----
This prevents problems when cross compiling. Using help2man is now also of
limited use; if we can just tell the user to use --help we do not need to keep
the manual in sync.
It also allows us to drop the several other supporting files that we use when
the help2man output isn't actually that useful.
Fixes https://github.com/fwupd/fwupd/issues/3025
We were seeing:
,----
| (dfu-tool:1139827): GLib-WARNING **: 17:34:42.671: GError set over the top of a previous GError or uninitialized memory.
| This indicates a bug in someone's code. You must ensure an error is NULL before it's set.
| The overwriting error message was: no device matches for 1234:abcd
`----
This is because we were attempting to overwrite libgusb's error with one
for fwupd, and glib rightfully complains. So let's prefix it instead.
There is a lot of code in fwupd that just assigns a shared object type to
a FuPlugin, and then for each device on that plugin assigns that same shared
object to each FuDevice.
Rather than proxy several kinds of information stores over two different levels
of abstraction create a 'context' which contains the shared *system* state
between the daemon, the plugins and the daemon.
This will allow us to hold other per-machine state in the future, for instance
the system battery level or AC state.
This allows us to 'nest' firmware formats, and removes a ton of duplication.
The aim here is to deprecate FuFirmwareImage -- it's almost always acting
as a 'child' FuFirmware instance, and even copies most of the vfuncs to allow
custom types. If I'm struggling to work out what should be a FuFirmware and
what should be a FuFirmwareImage then a plugin author has no hope.
For simple payloads we were adding bytes into an image and then the image into
a firmware. This gets really messy when most plugins are treating the FuFirmware
*as* the binary firmware file.
The GBytes saved in the FuFirmware would be considered the payload with the
aim of not using FuFirmwareImage in the single-image case.
Rather than trying to guess typos, force each plugin to register the quirk
keys it supports, so we can show a sensible warning if required at startup on
the console.
The best way of not getting something wrong is to not require it in the first
place...
All plugins now use DeviceInstanceId-style quirk matches and we can just drop
the prefix in all files. We were treating HwId=, Guid= and DeviceInstanceId= in
exactly the same way -- they're just converted to GUIDs when building the silo!
Devices may want to support more than one protocol, and for some devices
(e.g. Unifying peripherals stuck in bootloader mode) you might not even be able
to query for the correct protocol anyway.
It is far too easy to forget to set FWUPD_DEVICE_FLAG_NO_GUID_MATCHING for new
plugins, and without it it all works really well *until* a user has two devices
of the same type installed at the same time and then one 'disappears' for hard
to explain reasons. Typically we only need it for replug anyway!
Explicitly opt-in to this rarely-required behaviour, with the default to just
use the physical and logical IDs. Also document the update behavior for each
plugin to explain why the flag is being used.
This allows you to have two identical Unifying plugged in without one of them
being hidden from the user, at the same time allowing a HIDRAW<->USB transition
when going to and from bootloader and runtime modes.
This removes the workaround added in 99eb3f06b6.
Fixes https://github.com/fwupd/fwupd/issues/2915
This allows a device subclass to call the parent method after doing an initial
action, or even deliberately not call the *generic* parent method at all.
It also simplifies the plugins; you no longer have to remember what the plugin
is deriving from and accidentally clobber the wrong superclass method.