mirror of
https://git.proxmox.com/git/fwupd
synced 2025-08-13 19:08:34 +00:00
Allow the daemon to request interactive action from the end user
The "return error and hope the client resubmits the firmware again" pattern is clunky. There are two plugins doing this now, and about to be one more. This adds FwupdRequest which provides a structured way of asking the user to perform an action, e.g. to replug the device or to press a special key or button. This replaces much of the UpdateMessage and UpdateImage API although it is still used internally. Clients capable of processing the new DeviceRequest signal should add REQUESTS to their feature flags. Also, this allows us go back to the old meaning of _NEEDS_BOOTLOADER, which was "needs rebooting into a bootloader mode" rather than the slightly weird "user needs to do something and resubmit request".
This commit is contained in:
parent
a71f100e5a
commit
19abf996c7
@ -1,3 +1,3 @@
|
||||
[suppress_type]
|
||||
type_kind = enum
|
||||
changed_enumerators = FWUPD_ERROR_LAST,FWUPD_GUID_FLAG_LAST,FWUPD_INSTALL_FLAG_LAST,FWUPD_KEYRING_KIND_LAST,FWUPD_REMOTE_KIND_LAST,FWUPD_SELF_SIGN_FLAG_LAST,FWUPD_STATUS_LAST,FWUPD_TRUST_FLAG_LAST,FWUPD_UPDATE_STATE_LAST,FWUPD_VERSION_FORMAT_LAST,FWUPD_CLIENT_DOWNLOAD_FLAG_LAST
|
||||
changed_enumerators = FWUPD_ERROR_LAST,FWUPD_GUID_FLAG_LAST,FWUPD_INSTALL_FLAG_LAST,FWUPD_KEYRING_KIND_LAST,FWUPD_REMOTE_KIND_LAST,FWUPD_SELF_SIGN_FLAG_LAST,FWUPD_STATUS_LAST,FWUPD_TRUST_FLAG_LAST,FWUPD_UPDATE_STATE_LAST,FWUPD_VERSION_FORMAT_LAST,FWUPD_CLIENT_DOWNLOAD_FLAG_LAST,FWUPD_FEATURE_FLAG_LAST
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include "fwupd-security-attr-private.h"
|
||||
#include "fwupd-release-private.h"
|
||||
#include "fwupd-remote-private.h"
|
||||
#include "fwupd-request-private.h"
|
||||
|
||||
typedef GObject *(*FwupdClientObjectNewFunc) (void);
|
||||
|
||||
@ -83,6 +84,7 @@ enum {
|
||||
SIGNAL_DEVICE_ADDED,
|
||||
SIGNAL_DEVICE_REMOVED,
|
||||
SIGNAL_DEVICE_CHANGED,
|
||||
SIGNAL_DEVICE_REQUEST,
|
||||
SIGNAL_LAST
|
||||
};
|
||||
|
||||
@ -131,13 +133,13 @@ typedef struct {
|
||||
FwupdClient *self;
|
||||
gchar *property_name;
|
||||
guint signal_id;
|
||||
FwupdDevice *device;
|
||||
GObject *payload;
|
||||
} FwupdClientContextHelper;
|
||||
|
||||
static void
|
||||
fwupd_client_context_helper_free (FwupdClientContextHelper *helper)
|
||||
{
|
||||
g_clear_object (&helper->device);
|
||||
g_clear_object (&helper->payload);
|
||||
g_object_unref (helper->self);
|
||||
g_free (helper->property_name);
|
||||
g_free (helper);
|
||||
@ -176,9 +178,9 @@ fwupd_client_context_idle_cb (gpointer user_data)
|
||||
if (helper->property_name != NULL)
|
||||
fwupd_client_context_object_notify (self, helper->property_name);
|
||||
|
||||
/* device signal */
|
||||
if (helper->signal_id !=0 && helper->device != NULL)
|
||||
g_signal_emit (self, signals[helper->signal_id], 0, helper->device);
|
||||
/* payload signal */
|
||||
if (helper->signal_id != 0 && helper->payload != NULL)
|
||||
g_signal_emit (self, signals[helper->signal_id], 0, helper->payload);
|
||||
}
|
||||
|
||||
/* all done */
|
||||
@ -228,14 +230,14 @@ fwupd_client_object_notify (FwupdClient *self, const gchar *property_name)
|
||||
|
||||
/* run callback in the correct thread */
|
||||
static void
|
||||
fwupd_client_signal_emit_device (FwupdClient *self, guint signal_id, FwupdDevice *device)
|
||||
fwupd_client_signal_emit_object (FwupdClient *self, guint signal_id, GObject *payload)
|
||||
{
|
||||
FwupdClientPrivate *priv = GET_PRIVATE (self);
|
||||
FwupdClientContextHelper *helper = NULL;
|
||||
|
||||
/* shortcut */
|
||||
if (g_main_context_is_owner (priv->main_ctx)) {
|
||||
g_signal_emit (self, signals[signal_id], 0, device);
|
||||
g_signal_emit (self, signals[signal_id], 0, payload);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -243,7 +245,7 @@ fwupd_client_signal_emit_device (FwupdClient *self, guint signal_id, FwupdDevice
|
||||
helper = g_new0 (FwupdClientContextHelper, 1);
|
||||
helper->self = g_object_ref (self);
|
||||
helper->signal_id = signal_id;
|
||||
helper->device = g_object_ref (device);
|
||||
helper->payload = g_object_ref (payload);
|
||||
fwupd_client_context_helper (self, helper);
|
||||
}
|
||||
|
||||
@ -407,21 +409,36 @@ fwupd_client_signal_cb (GDBusProxy *proxy,
|
||||
dev = fwupd_device_from_variant (parameters);
|
||||
g_debug ("Emitting ::device-added(%s)",
|
||||
fwupd_device_get_id (dev));
|
||||
fwupd_client_signal_emit_device (self, SIGNAL_DEVICE_ADDED, dev);
|
||||
fwupd_client_signal_emit_object (self,
|
||||
SIGNAL_DEVICE_ADDED,
|
||||
G_OBJECT (dev));
|
||||
return;
|
||||
}
|
||||
if (g_strcmp0 (signal_name, "DeviceRemoved") == 0) {
|
||||
dev = fwupd_device_from_variant (parameters);
|
||||
g_debug ("Emitting ::device-removed(%s)",
|
||||
fwupd_device_get_id (dev));
|
||||
fwupd_client_signal_emit_device (self, SIGNAL_DEVICE_REMOVED, dev);
|
||||
fwupd_client_signal_emit_object (self,
|
||||
SIGNAL_DEVICE_REMOVED,
|
||||
G_OBJECT (dev));
|
||||
return;
|
||||
}
|
||||
if (g_strcmp0 (signal_name, "DeviceChanged") == 0) {
|
||||
dev = fwupd_device_from_variant (parameters);
|
||||
g_debug ("Emitting ::device-changed(%s)",
|
||||
fwupd_device_get_id (dev));
|
||||
fwupd_client_signal_emit_device (self, SIGNAL_DEVICE_CHANGED, dev);
|
||||
fwupd_client_signal_emit_object (self,
|
||||
SIGNAL_DEVICE_CHANGED,
|
||||
G_OBJECT (dev));
|
||||
return;
|
||||
}
|
||||
if (g_strcmp0 (signal_name, "DeviceRequest") == 0) {
|
||||
g_autoptr(FwupdRequest) req = fwupd_request_from_variant (parameters);
|
||||
g_debug ("Emitting ::device-request(%s)",
|
||||
fwupd_request_get_id (req));
|
||||
fwupd_client_signal_emit_object (self,
|
||||
SIGNAL_DEVICE_REQUEST,
|
||||
G_OBJECT (req));
|
||||
return;
|
||||
}
|
||||
g_debug ("Unknown signal name '%s' from %s", signal_name, sender_name);
|
||||
@ -4952,6 +4969,23 @@ fwupd_client_class_init (FwupdClientClass *klass)
|
||||
NULL, NULL, g_cclosure_marshal_generic,
|
||||
G_TYPE_NONE, 1, FWUPD_TYPE_DEVICE);
|
||||
|
||||
/**
|
||||
* FwupdClient::device-request:
|
||||
* @self: the #FwupdClient instance that emitted the signal
|
||||
* @msg: the #FwupdRequest
|
||||
*
|
||||
* The ::device-request signal is emitted when a device has been
|
||||
* emitted some kind of event, e.g. a manual action is required.
|
||||
*
|
||||
* Since: 1.6.2
|
||||
**/
|
||||
signals [SIGNAL_DEVICE_REQUEST] =
|
||||
g_signal_new ("device-request",
|
||||
G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (FwupdClientClass, device_changed),
|
||||
NULL, NULL, g_cclosure_marshal_generic,
|
||||
G_TYPE_NONE, 1, FWUPD_TYPE_REQUEST);
|
||||
|
||||
/**
|
||||
* FwupdClient:status:
|
||||
*
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
#include "fwupd-enums.h"
|
||||
#include "fwupd-device.h"
|
||||
#include "fwupd-request.h"
|
||||
#include "fwupd-plugin.h"
|
||||
#include "fwupd-remote.h"
|
||||
|
||||
@ -31,6 +32,8 @@ struct _FwupdClientClass
|
||||
FwupdDevice *result);
|
||||
void (*device_changed) (FwupdClient *client,
|
||||
FwupdDevice *result);
|
||||
void (*device_request) (FwupdClient *client,
|
||||
FwupdRequest *request);
|
||||
/*< private >*/
|
||||
void (*_fwupd_reserved1) (void);
|
||||
void (*_fwupd_reserved2) (void);
|
||||
@ -38,7 +41,6 @@ struct _FwupdClientClass
|
||||
void (*_fwupd_reserved4) (void);
|
||||
void (*_fwupd_reserved5) (void);
|
||||
void (*_fwupd_reserved6) (void);
|
||||
void (*_fwupd_reserved7) (void);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -138,6 +138,14 @@ G_BEGIN_DECLS
|
||||
* The D-Bus type signature string is 'u' i.e. a unsigned 32 bit integer.
|
||||
**/
|
||||
#define FWUPD_RESULT_KEY_URGENCY "Urgency"
|
||||
/**
|
||||
* FWUPD_RESULT_KEY_REQUEST_KIND:
|
||||
*
|
||||
* Result key to represent RequestKind
|
||||
*
|
||||
* The D-Bus type signature string is 'u' i.e. a unsigned 32 bit integer.
|
||||
**/
|
||||
#define FWUPD_RESULT_KEY_REQUEST_KIND "RequestKind"
|
||||
/**
|
||||
* FWUPD_RESULT_KEY_HSI_LEVEL:
|
||||
*
|
||||
|
@ -513,6 +513,8 @@ fwupd_feature_flag_to_string (FwupdFeatureFlags feature_flag)
|
||||
return "update-action";
|
||||
if (feature_flag == FWUPD_FEATURE_FLAG_SWITCH_BRANCH)
|
||||
return "switch-branch";
|
||||
if (feature_flag == FWUPD_FEATURE_FLAG_REQUESTS)
|
||||
return "requests";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -539,6 +541,8 @@ fwupd_feature_flag_from_string (const gchar *feature_flag)
|
||||
return FWUPD_FEATURE_FLAG_UPDATE_ACTION;
|
||||
if (g_strcmp0 (feature_flag, "switch-branch") == 0)
|
||||
return FWUPD_FEATURE_FLAG_SWITCH_BRANCH;
|
||||
if (g_strcmp0 (feature_flag, "requests") == 0)
|
||||
return FWUPD_FEATURE_FLAG_REQUESTS;
|
||||
return FWUPD_FEATURE_FLAG_LAST;
|
||||
}
|
||||
|
||||
|
@ -71,6 +71,7 @@ typedef enum {
|
||||
* @FWUPD_FEATURE_FLAG_DETACH_ACTION: Can perform detach action, typically showing text
|
||||
* @FWUPD_FEATURE_FLAG_UPDATE_ACTION: Can perform update action, typically showing text
|
||||
* @FWUPD_FEATURE_FLAG_SWITCH_BRANCH: Can switch the firmware branch
|
||||
* @FWUPD_FEATURE_FLAG_REQUESTS: Can show interactive requests
|
||||
*
|
||||
* The flags to the feature capabilities of the front-end client.
|
||||
**/
|
||||
@ -80,6 +81,7 @@ typedef enum {
|
||||
FWUPD_FEATURE_FLAG_DETACH_ACTION = 1 << 1, /* Since: 1.4.5 */
|
||||
FWUPD_FEATURE_FLAG_UPDATE_ACTION = 1 << 2, /* Since: 1.4.5 */
|
||||
FWUPD_FEATURE_FLAG_SWITCH_BRANCH = 1 << 3, /* Since: 1.5.0 */
|
||||
FWUPD_FEATURE_FLAG_REQUESTS = 1 << 4, /* Since: 1.6.2 */
|
||||
/*< private >*/
|
||||
FWUPD_FEATURE_FLAG_LAST
|
||||
} FwupdFeatureFlags;
|
||||
|
15
libfwupd/fwupd-request-private.h
Normal file
15
libfwupd/fwupd-request-private.h
Normal file
@ -0,0 +1,15 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Richard Hughes <richard@hughsie.com>
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1+
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "fwupd-request.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
GVariant *fwupd_request_to_variant (FwupdRequest *self);
|
||||
|
||||
G_END_DECLS
|
626
libfwupd/fwupd-request.c
Normal file
626
libfwupd/fwupd-request.c
Normal file
@ -0,0 +1,626 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Richard Hughes <richard@hughsie.com>
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1+
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "fwupd-enums-private.h"
|
||||
#include "fwupd-request-private.h"
|
||||
|
||||
/**
|
||||
* FwupdRequest:
|
||||
*
|
||||
* A user request from the device.
|
||||
*
|
||||
* See also: [class@FwupdDevice]
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
gchar *id;
|
||||
FwupdRequestKind kind;
|
||||
guint64 created;
|
||||
gchar *device_id;
|
||||
gchar *message;
|
||||
gchar *image;
|
||||
} FwupdRequestPrivate;
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_ID,
|
||||
PROP_KIND,
|
||||
PROP_MESSAGE,
|
||||
PROP_IMAGE,
|
||||
PROP_LAST
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (FwupdRequest, fwupd_request, G_TYPE_OBJECT)
|
||||
#define GET_PRIVATE(o) (fwupd_request_get_instance_private (o))
|
||||
|
||||
/**
|
||||
* fwupd_request_kind_to_string:
|
||||
* @kind: a update message kind, e.g. %FWUPD_REQUEST_KIND_IMMEDIATE
|
||||
*
|
||||
* Converts a enumerated update message kind to a string.
|
||||
*
|
||||
* Returns: identifier string
|
||||
*
|
||||
* Since: 1.6.2
|
||||
**/
|
||||
const gchar *
|
||||
fwupd_request_kind_to_string (FwupdRequestKind kind)
|
||||
{
|
||||
if (kind == FWUPD_REQUEST_KIND_UNKNOWN)
|
||||
return "unknown";
|
||||
if (kind == FWUPD_REQUEST_KIND_POST)
|
||||
return "post";
|
||||
if (kind == FWUPD_REQUEST_KIND_IMMEDIATE)
|
||||
return "immediate";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* fwupd_request_kind_from_string:
|
||||
* @kind: a string, e.g. `immediate`
|
||||
*
|
||||
* Converts a string to an enumerated update message kind.
|
||||
*
|
||||
* Returns: enumerated value
|
||||
*
|
||||
* Since: 1.6.2
|
||||
**/
|
||||
FwupdRequestKind
|
||||
fwupd_request_kind_from_string (const gchar *kind)
|
||||
{
|
||||
if (g_strcmp0 (kind, "unknown") == 0)
|
||||
return FWUPD_REQUEST_KIND_UNKNOWN;
|
||||
if (g_strcmp0 (kind, "post") == 0)
|
||||
return FWUPD_REQUEST_KIND_POST;
|
||||
if (g_strcmp0 (kind, "immediate") == 0)
|
||||
return FWUPD_REQUEST_KIND_IMMEDIATE;
|
||||
return FWUPD_REQUEST_KIND_LAST;
|
||||
}
|
||||
|
||||
/**
|
||||
* fwupd_request_get_id:
|
||||
* @self: a #FwupdRequest
|
||||
*
|
||||
* Gets the ID.
|
||||
*
|
||||
* Returns: the ID, or %NULL if unset
|
||||
*
|
||||
* Since: 1.6.2
|
||||
**/
|
||||
const gchar *
|
||||
fwupd_request_get_id (FwupdRequest *self)
|
||||
{
|
||||
FwupdRequestPrivate *priv = GET_PRIVATE (self);
|
||||
g_return_val_if_fail (FWUPD_IS_REQUEST (self), NULL);
|
||||
return priv->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* fwupd_request_set_id:
|
||||
* @self: a #FwupdRequest
|
||||
* @id: (nullable): the request ID, e.g. `USB:foo`
|
||||
*
|
||||
* Sets the ID.
|
||||
*
|
||||
* Since: 1.6.2
|
||||
**/
|
||||
void
|
||||
fwupd_request_set_id (FwupdRequest *self, const gchar *id)
|
||||
{
|
||||
FwupdRequestPrivate *priv = GET_PRIVATE (self);
|
||||
g_return_if_fail (FWUPD_IS_REQUEST (self));
|
||||
|
||||
/* not changed */
|
||||
if (g_strcmp0 (priv->id, id) == 0)
|
||||
return;
|
||||
|
||||
g_free (priv->id);
|
||||
priv->id = g_strdup (id);
|
||||
}
|
||||
|
||||
/**
|
||||
* fwupd_request_get_device_id:
|
||||
* @self: a #FwupdRequest
|
||||
*
|
||||
* Gets the device_id that created the request.
|
||||
*
|
||||
* Returns: the device_id, or %NULL if unset
|
||||
*
|
||||
* Since: 1.6.2
|
||||
**/
|
||||
const gchar *
|
||||
fwupd_request_get_device_id (FwupdRequest *self)
|
||||
{
|
||||
FwupdRequestPrivate *priv = GET_PRIVATE (self);
|
||||
g_return_val_if_fail (FWUPD_IS_REQUEST (self), NULL);
|
||||
return priv->device_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* fwupd_request_set_device_id:
|
||||
* @self: a #FwupdRequest
|
||||
* @device_id: (nullable): the device_id, e.g. `colorhug`
|
||||
*
|
||||
* Sets the device_id that created the request.
|
||||
*
|
||||
* Since: 1.6.2
|
||||
**/
|
||||
void
|
||||
fwupd_request_set_device_id (FwupdRequest *self, const gchar *device_id)
|
||||
{
|
||||
FwupdRequestPrivate *priv = GET_PRIVATE (self);
|
||||
g_return_if_fail (FWUPD_IS_REQUEST (self));
|
||||
|
||||
/* not changed */
|
||||
if (g_strcmp0 (priv->device_id, device_id) == 0)
|
||||
return;
|
||||
|
||||
g_free (priv->device_id);
|
||||
priv->device_id = g_strdup (device_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* fwupd_request_get_created:
|
||||
* @self: a #FwupdRequest
|
||||
*
|
||||
* Gets when the request was created.
|
||||
*
|
||||
* Returns: the UNIX time, or 0 if unset
|
||||
*
|
||||
* Since: 1.6.2
|
||||
**/
|
||||
guint64
|
||||
fwupd_request_get_created (FwupdRequest *self)
|
||||
{
|
||||
FwupdRequestPrivate *priv = GET_PRIVATE (self);
|
||||
g_return_val_if_fail (FWUPD_IS_REQUEST (self), 0);
|
||||
return priv->created;
|
||||
}
|
||||
|
||||
/**
|
||||
* fwupd_request_set_created:
|
||||
* @self: a #FwupdRequest
|
||||
* @created: the UNIX time
|
||||
*
|
||||
* Sets when the request was created.
|
||||
*
|
||||
* Since: 1.6.2
|
||||
**/
|
||||
void
|
||||
fwupd_request_set_created (FwupdRequest *self, guint64 created)
|
||||
{
|
||||
FwupdRequestPrivate *priv = GET_PRIVATE (self);
|
||||
g_return_if_fail (FWUPD_IS_REQUEST (self));
|
||||
priv->created = created;
|
||||
}
|
||||
|
||||
/**
|
||||
* fwupd_request_to_variant:
|
||||
* @self: a #FwupdRequest
|
||||
*
|
||||
* Serialize the request data.
|
||||
*
|
||||
* Returns: the serialized data, or %NULL for error
|
||||
*
|
||||
* Since: 1.6.2
|
||||
**/
|
||||
GVariant *
|
||||
fwupd_request_to_variant (FwupdRequest *self)
|
||||
{
|
||||
FwupdRequestPrivate *priv = GET_PRIVATE (self);
|
||||
GVariantBuilder builder;
|
||||
|
||||
g_return_val_if_fail (FWUPD_IS_REQUEST (self), NULL);
|
||||
|
||||
/* create an array with all the metadata in */
|
||||
g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT);
|
||||
if (priv->id != NULL) {
|
||||
g_variant_builder_add (&builder, "{sv}",
|
||||
FWUPD_RESULT_KEY_APPSTREAM_ID,
|
||||
g_variant_new_string (priv->id));
|
||||
}
|
||||
if (priv->created > 0) {
|
||||
g_variant_builder_add (&builder, "{sv}",
|
||||
FWUPD_RESULT_KEY_CREATED,
|
||||
g_variant_new_uint64 (priv->created));
|
||||
}
|
||||
if (priv->device_id != NULL) {
|
||||
g_variant_builder_add (&builder, "{sv}",
|
||||
FWUPD_RESULT_KEY_PLUGIN,
|
||||
g_variant_new_string (priv->device_id));
|
||||
}
|
||||
if (priv->message != NULL) {
|
||||
g_variant_builder_add (&builder, "{sv}",
|
||||
FWUPD_RESULT_KEY_UPDATE_MESSAGE,
|
||||
g_variant_new_string (priv->message));
|
||||
}
|
||||
if (priv->image != NULL) {
|
||||
g_variant_builder_add (&builder, "{sv}",
|
||||
FWUPD_RESULT_KEY_UPDATE_IMAGE,
|
||||
g_variant_new_string (priv->image));
|
||||
}
|
||||
if (priv->kind != FWUPD_REQUEST_KIND_UNKNOWN) {
|
||||
g_variant_builder_add (&builder, "{sv}",
|
||||
FWUPD_RESULT_KEY_REQUEST_KIND,
|
||||
g_variant_new_uint32 (priv->kind));
|
||||
}
|
||||
return g_variant_new ("a{sv}", &builder);
|
||||
}
|
||||
|
||||
static void
|
||||
fwupd_request_from_key_value (FwupdRequest *self, const gchar *key, GVariant *value)
|
||||
{
|
||||
if (g_strcmp0 (key, FWUPD_RESULT_KEY_APPSTREAM_ID) == 0) {
|
||||
fwupd_request_set_id (self, g_variant_get_string (value, NULL));
|
||||
return;
|
||||
}
|
||||
if (g_strcmp0 (key, FWUPD_RESULT_KEY_CREATED) == 0) {
|
||||
fwupd_request_set_created (self, g_variant_get_uint64 (value));
|
||||
return;
|
||||
}
|
||||
if (g_strcmp0 (key, FWUPD_RESULT_KEY_DEVICE_ID) == 0) {
|
||||
fwupd_request_set_device_id (self, g_variant_get_string (value, NULL));
|
||||
return;
|
||||
}
|
||||
if (g_strcmp0 (key, FWUPD_RESULT_KEY_UPDATE_MESSAGE) == 0) {
|
||||
fwupd_request_set_message (self, g_variant_get_string (value, NULL));
|
||||
return;
|
||||
}
|
||||
if (g_strcmp0 (key, FWUPD_RESULT_KEY_UPDATE_IMAGE) == 0) {
|
||||
fwupd_request_set_image (self, g_variant_get_string (value, NULL));
|
||||
return;
|
||||
}
|
||||
if (g_strcmp0 (key, FWUPD_RESULT_KEY_REQUEST_KIND) == 0) {
|
||||
fwupd_request_set_kind (self, g_variant_get_uint32 (value));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
fwupd_pad_kv_str (GString *str, const gchar *key, const gchar *value)
|
||||
{
|
||||
/* ignore */
|
||||
if (key == NULL || value == NULL)
|
||||
return;
|
||||
g_string_append_printf (str, " %s: ", key);
|
||||
for (gsize i = strlen (key); i < 20; i++)
|
||||
g_string_append (str, " ");
|
||||
g_string_append_printf (str, "%s\n", value);
|
||||
}
|
||||
|
||||
static void
|
||||
fwupd_pad_kv_unx (GString *str, const gchar *key, guint64 value)
|
||||
{
|
||||
g_autoptr(GDateTime) date = NULL;
|
||||
g_autofree gchar *tmp = NULL;
|
||||
|
||||
/* ignore */
|
||||
if (value == 0)
|
||||
return;
|
||||
|
||||
date = g_date_time_new_from_unix_utc ((gint64) value);
|
||||
tmp = g_date_time_format (date, "%F");
|
||||
fwupd_pad_kv_str (str, key, tmp);
|
||||
}
|
||||
|
||||
/**
|
||||
* fwupd_request_get_message:
|
||||
* @self: a #FwupdRequest
|
||||
*
|
||||
* Gets the update message.
|
||||
*
|
||||
* Returns: the update message, or %NULL if unset
|
||||
*
|
||||
* Since: 1.6.2
|
||||
**/
|
||||
const gchar *
|
||||
fwupd_request_get_message (FwupdRequest *self)
|
||||
{
|
||||
FwupdRequestPrivate *priv = GET_PRIVATE (self);
|
||||
g_return_val_if_fail (FWUPD_IS_REQUEST (self), NULL);
|
||||
return priv->message;
|
||||
}
|
||||
|
||||
/**
|
||||
* fwupd_request_set_message:
|
||||
* @self: a #FwupdRequest
|
||||
* @message: (nullable): the update message string
|
||||
*
|
||||
* Sets the update message.
|
||||
*
|
||||
* Since: 1.6.2
|
||||
**/
|
||||
void
|
||||
fwupd_request_set_message (FwupdRequest *self, const gchar *message)
|
||||
{
|
||||
FwupdRequestPrivate *priv = GET_PRIVATE (self);
|
||||
g_return_if_fail (FWUPD_IS_REQUEST (self));
|
||||
|
||||
/* not changed */
|
||||
if (g_strcmp0 (priv->message, message) == 0)
|
||||
return;
|
||||
|
||||
g_free (priv->message);
|
||||
priv->message = g_strdup (message);
|
||||
g_object_notify (G_OBJECT (self), "message");
|
||||
}
|
||||
|
||||
/**
|
||||
* fwupd_request_get_image:
|
||||
* @self: a #FwupdRequest
|
||||
*
|
||||
* Gets the update image.
|
||||
*
|
||||
* Returns: the update image URL, or %NULL if unset
|
||||
*
|
||||
* Since: 1.6.2
|
||||
**/
|
||||
const gchar *
|
||||
fwupd_request_get_image (FwupdRequest *self)
|
||||
{
|
||||
FwupdRequestPrivate *priv = GET_PRIVATE (self);
|
||||
g_return_val_if_fail (FWUPD_IS_REQUEST (self), NULL);
|
||||
return priv->image;
|
||||
}
|
||||
|
||||
/**
|
||||
* fwupd_request_set_image:
|
||||
* @self: a #FwupdRequest
|
||||
* @image: (nullable): the update image URL
|
||||
*
|
||||
* Sets the update image.
|
||||
*
|
||||
* Since: 1.6.2
|
||||
**/
|
||||
void
|
||||
fwupd_request_set_image (FwupdRequest *self, const gchar *image)
|
||||
{
|
||||
FwupdRequestPrivate *priv = GET_PRIVATE (self);
|
||||
g_return_if_fail (FWUPD_IS_REQUEST (self));
|
||||
|
||||
/* not changed */
|
||||
if (g_strcmp0 (priv->image, image) == 0)
|
||||
return;
|
||||
|
||||
g_free (priv->image);
|
||||
priv->image = g_strdup (image);
|
||||
g_object_notify (G_OBJECT (self), "image");
|
||||
}
|
||||
|
||||
/**
|
||||
* fwupd_request_get_kind:
|
||||
* @self: a #FwupdRequest
|
||||
*
|
||||
* Returns what the request is currently doing.
|
||||
*
|
||||
* Returns: the kind value, e.g. %FWUPD_STATUS_REQUEST_WRITE
|
||||
*
|
||||
* Since: 1.6.2
|
||||
**/
|
||||
FwupdRequestKind
|
||||
fwupd_request_get_kind (FwupdRequest *self)
|
||||
{
|
||||
FwupdRequestPrivate *priv = GET_PRIVATE (self);
|
||||
g_return_val_if_fail (FWUPD_IS_REQUEST (self), 0);
|
||||
return priv->kind;
|
||||
}
|
||||
|
||||
/**
|
||||
* fwupd_request_set_kind:
|
||||
* @self: a #FwupdRequest
|
||||
* @kind: the kind value, e.g. %FWUPD_STATUS_REQUEST_WRITE
|
||||
*
|
||||
* Sets what the request is currently doing.
|
||||
*
|
||||
* Since: 1.6.2
|
||||
**/
|
||||
void
|
||||
fwupd_request_set_kind (FwupdRequest *self, FwupdRequestKind kind)
|
||||
{
|
||||
FwupdRequestPrivate *priv = GET_PRIVATE (self);
|
||||
g_return_if_fail (FWUPD_IS_REQUEST (self));
|
||||
if (priv->kind == kind)
|
||||
return;
|
||||
priv->kind = kind;
|
||||
g_object_notify (G_OBJECT (self), "kind");
|
||||
}
|
||||
|
||||
/**
|
||||
* fwupd_request_to_string:
|
||||
* @self: a #FwupdRequest
|
||||
*
|
||||
* Builds a text representation of the object.
|
||||
*
|
||||
* Returns: text, or %NULL for invalid
|
||||
*
|
||||
* Since: 1.6.2
|
||||
**/
|
||||
gchar *
|
||||
fwupd_request_to_string (FwupdRequest *self)
|
||||
{
|
||||
FwupdRequestPrivate *priv = GET_PRIVATE (self);
|
||||
GString *str = g_string_new (NULL);
|
||||
|
||||
g_return_val_if_fail (FWUPD_IS_REQUEST (self), NULL);
|
||||
|
||||
fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_APPSTREAM_ID, priv->id);
|
||||
if (priv->kind != FWUPD_REQUEST_KIND_UNKNOWN) {
|
||||
fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_REQUEST_KIND,
|
||||
fwupd_request_kind_to_string (priv->kind));
|
||||
}
|
||||
fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_DEVICE_ID, priv->device_id);
|
||||
fwupd_pad_kv_unx (str, FWUPD_RESULT_KEY_CREATED, priv->created);
|
||||
fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_UPDATE_MESSAGE, priv->message);
|
||||
fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_UPDATE_IMAGE, priv->image);
|
||||
return g_string_free (str, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
fwupd_request_get_property (GObject *object, guint prop_id,
|
||||
GValue *value, GParamSpec *pspec)
|
||||
{
|
||||
FwupdRequest *self = FWUPD_REQUEST (object);
|
||||
FwupdRequestPrivate *priv = GET_PRIVATE (self);
|
||||
switch (prop_id) {
|
||||
case PROP_ID:
|
||||
g_value_set_string (value, priv->id);
|
||||
break;
|
||||
case PROP_MESSAGE:
|
||||
g_value_set_string (value, priv->message);
|
||||
break;
|
||||
case PROP_IMAGE:
|
||||
g_value_set_string (value, priv->image);
|
||||
break;
|
||||
case PROP_KIND:
|
||||
g_value_set_uint (value, priv->kind);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
fwupd_request_set_property (GObject *object, guint prop_id,
|
||||
const GValue *value, GParamSpec *pspec)
|
||||
{
|
||||
FwupdRequest *self = FWUPD_REQUEST (object);
|
||||
switch (prop_id) {
|
||||
case PROP_ID:
|
||||
fwupd_request_set_id (self, g_value_get_string (value));
|
||||
break;
|
||||
case PROP_MESSAGE:
|
||||
fwupd_request_set_message (self, g_value_get_string (value));
|
||||
break;
|
||||
case PROP_IMAGE:
|
||||
fwupd_request_set_image (self, g_value_get_string (value));
|
||||
break;
|
||||
case PROP_KIND:
|
||||
fwupd_request_set_kind (self, g_value_get_uint (value));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
fwupd_request_finalize (GObject *object)
|
||||
{
|
||||
FwupdRequest *self = FWUPD_REQUEST (object);
|
||||
FwupdRequestPrivate *priv = GET_PRIVATE (self);
|
||||
|
||||
g_free (priv->id);
|
||||
g_free (priv->device_id);
|
||||
g_free (priv->message);
|
||||
g_free (priv->image);
|
||||
|
||||
G_OBJECT_CLASS (fwupd_request_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
fwupd_request_init (FwupdRequest *self)
|
||||
{
|
||||
FwupdRequestPrivate *priv = GET_PRIVATE (self);
|
||||
priv->created = g_get_real_time () / G_USEC_PER_SEC;
|
||||
}
|
||||
|
||||
static void
|
||||
fwupd_request_class_init (FwupdRequestClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GParamSpec *pspec;
|
||||
|
||||
object_class->finalize = fwupd_request_finalize;
|
||||
object_class->get_property = fwupd_request_get_property;
|
||||
object_class->set_property = fwupd_request_set_property;
|
||||
|
||||
pspec = g_param_spec_string ("id", NULL, NULL, NULL,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_NAME);
|
||||
g_object_class_install_property (object_class, PROP_ID, pspec);
|
||||
|
||||
pspec = g_param_spec_uint ("kind", NULL, NULL,
|
||||
FWUPD_REQUEST_KIND_UNKNOWN,
|
||||
FWUPD_REQUEST_KIND_LAST,
|
||||
FWUPD_REQUEST_KIND_UNKNOWN,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_NAME);
|
||||
g_object_class_install_property (object_class, PROP_KIND, pspec);
|
||||
|
||||
pspec = g_param_spec_string ("message", NULL, NULL, NULL,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_NAME);
|
||||
g_object_class_install_property (object_class, PROP_MESSAGE, pspec);
|
||||
|
||||
pspec = g_param_spec_string ("image", NULL, NULL, NULL,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_NAME);
|
||||
g_object_class_install_property (object_class, PROP_IMAGE, pspec);
|
||||
}
|
||||
|
||||
static void
|
||||
fwupd_request_set_from_variant_iter (FwupdRequest *self, GVariantIter *iter)
|
||||
{
|
||||
GVariant *value;
|
||||
const gchar *key;
|
||||
while (g_variant_iter_next (iter, "{&sv}", &key, &value)) {
|
||||
fwupd_request_from_key_value (self, key, value);
|
||||
g_variant_unref (value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* fwupd_request_from_variant:
|
||||
* @value: the serialized data
|
||||
*
|
||||
* Creates a new request using serialized data.
|
||||
*
|
||||
* Returns: (transfer full): a new #FwupdRequest, or %NULL if @value was invalid
|
||||
*
|
||||
* Since: 1.6.2
|
||||
**/
|
||||
FwupdRequest *
|
||||
fwupd_request_from_variant (GVariant *value)
|
||||
{
|
||||
FwupdRequest *self = NULL;
|
||||
const gchar *type_string;
|
||||
g_autoptr(GVariantIter) iter = NULL;
|
||||
|
||||
/* format from GetDetails */
|
||||
type_string = g_variant_get_type_string (value);
|
||||
if (g_strcmp0 (type_string, "(a{sv})") == 0) {
|
||||
self = fwupd_request_new ();
|
||||
g_variant_get (value, "(a{sv})", &iter);
|
||||
fwupd_request_set_from_variant_iter (self, iter);
|
||||
} else if (g_strcmp0 (type_string, "a{sv}") == 0) {
|
||||
self = fwupd_request_new ();
|
||||
g_variant_get (value, "a{sv}", &iter);
|
||||
fwupd_request_set_from_variant_iter (self, iter);
|
||||
} else {
|
||||
g_warning ("type %s not known", type_string);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
/**
|
||||
* fwupd_request_new:
|
||||
*
|
||||
* Creates a new request.
|
||||
*
|
||||
* Returns: a new #FwupdRequest
|
||||
*
|
||||
* Since: 1.6.2
|
||||
**/
|
||||
FwupdRequest *
|
||||
fwupd_request_new (void)
|
||||
{
|
||||
FwupdRequest *self;
|
||||
self = g_object_new (FWUPD_TYPE_REQUEST, NULL);
|
||||
return FWUPD_REQUEST (self);
|
||||
}
|
90
libfwupd/fwupd-request.h
Normal file
90
libfwupd/fwupd-request.h
Normal file
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Richard Hughes <richard@hughsie.com>
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1+
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define FWUPD_TYPE_REQUEST (fwupd_request_get_type ())
|
||||
G_DECLARE_DERIVABLE_TYPE (FwupdRequest, fwupd_request, FWUPD, REQUEST, GObject)
|
||||
|
||||
struct _FwupdRequestClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
/*< private >*/
|
||||
void (*_fwupd_reserved1) (void);
|
||||
void (*_fwupd_reserved2) (void);
|
||||
void (*_fwupd_reserved3) (void);
|
||||
void (*_fwupd_reserved4) (void);
|
||||
void (*_fwupd_reserved5) (void);
|
||||
void (*_fwupd_reserved6) (void);
|
||||
void (*_fwupd_reserved7) (void);
|
||||
};
|
||||
|
||||
/**
|
||||
* FwupdRequestKind:
|
||||
* @FWUPD_REQUEST_KIND_UNKNOWN: Unknown kind
|
||||
* @FWUPD_REQUEST_KIND_POST: After the update
|
||||
* @FWUPD_REQUEST_KIND_IMMEDIATE: Immediately
|
||||
*
|
||||
* The kind of request we are asking of the user.
|
||||
**/
|
||||
typedef enum {
|
||||
FWUPD_REQUEST_KIND_UNKNOWN, /* Since: 1.6.2 */
|
||||
FWUPD_REQUEST_KIND_POST, /* Since: 1.6.2 */
|
||||
FWUPD_REQUEST_KIND_IMMEDIATE, /* Since: 1.6.2 */
|
||||
/*< private >*/
|
||||
FWUPD_REQUEST_KIND_LAST
|
||||
} FwupdRequestKind;
|
||||
|
||||
/**
|
||||
* FWPUD_REQUEST_ID_REMOVE_REPLUG:
|
||||
*
|
||||
* The user needs to remove and reinsert the device.
|
||||
*
|
||||
* Since 1.6.2
|
||||
*/
|
||||
#define FWPUD_REQUEST_ID_REMOVE_REPLUG "org.freedesktop.fwupd.request.remove-replug"
|
||||
|
||||
/**
|
||||
* FWPUD_REQUEST_ID_PRESS_UNLOCK:
|
||||
*
|
||||
* The user needs to press unlock on the device.
|
||||
*
|
||||
* Since 1.6.2
|
||||
*/
|
||||
#define FWPUD_REQUEST_ID_PRESS_UNLOCK "org.freedesktop.fwupd.request.press-unlock"
|
||||
|
||||
const gchar *fwupd_request_kind_to_string (FwupdRequestKind kind);
|
||||
FwupdRequestKind fwupd_request_kind_from_string (const gchar *kind);
|
||||
|
||||
FwupdRequest *fwupd_request_new (void);
|
||||
gchar *fwupd_request_to_string (FwupdRequest *self);
|
||||
|
||||
const gchar *fwupd_request_get_id (FwupdRequest *self);
|
||||
void fwupd_request_set_id (FwupdRequest *self,
|
||||
const gchar *id);
|
||||
guint64 fwupd_request_get_created (FwupdRequest *self);
|
||||
void fwupd_request_set_created (FwupdRequest *self,
|
||||
guint64 created);
|
||||
const gchar *fwupd_request_get_device_id (FwupdRequest *self);
|
||||
void fwupd_request_set_device_id (FwupdRequest *self,
|
||||
const gchar *device_id);
|
||||
const gchar *fwupd_request_get_message (FwupdRequest *self);
|
||||
void fwupd_request_set_message (FwupdRequest *self,
|
||||
const gchar *message);
|
||||
const gchar *fwupd_request_get_image (FwupdRequest *self);
|
||||
void fwupd_request_set_image (FwupdRequest *self,
|
||||
const gchar *image);
|
||||
FwupdRequestKind fwupd_request_get_kind (FwupdRequest *self);
|
||||
void fwupd_request_set_kind (FwupdRequest *self,
|
||||
FwupdRequestKind kind);
|
||||
|
||||
FwupdRequest *fwupd_request_from_variant (GVariant *value);
|
||||
|
||||
G_END_DECLS
|
@ -20,6 +20,7 @@
|
||||
#include "fwupd-device-private.h"
|
||||
#include "fwupd-release-private.h"
|
||||
#include "fwupd-remote-private.h"
|
||||
#include "fwupd-request-private.h"
|
||||
|
||||
static gboolean
|
||||
fu_test_compare_lines (const gchar *txt1, const gchar *txt2, GError **error)
|
||||
@ -131,6 +132,11 @@ fwupd_enums_func (void)
|
||||
g_assert_cmpstr (tmp, !=, NULL);
|
||||
g_assert_cmpint (fwupd_trust_flag_from_string (tmp), ==, i);
|
||||
}
|
||||
for (guint i = 0; i < FWUPD_REQUEST_KIND_LAST; i++) {
|
||||
const gchar *tmp = fwupd_request_kind_to_string (i);
|
||||
g_assert_cmpstr (tmp, !=, NULL);
|
||||
g_assert_cmpint (fwupd_request_kind_from_string (tmp), ==, i);
|
||||
}
|
||||
for (guint i = FWUPD_RELEASE_URGENCY_UNKNOWN + 1; i < FWUPD_RELEASE_URGENCY_LAST; i++) {
|
||||
const gchar *tmp = fwupd_release_urgency_to_string (i);
|
||||
g_assert_cmpstr (tmp, !=, NULL);
|
||||
@ -345,6 +351,35 @@ fwupd_release_func (void)
|
||||
g_assert_cmpstr (fwupd_release_get_metadata_item (release2, "baz"), ==, "bam");
|
||||
}
|
||||
|
||||
static void
|
||||
fwupd_request_func (void)
|
||||
{
|
||||
g_autofree gchar *str = NULL;
|
||||
g_autoptr(FwupdRequest) request = fwupd_request_new ();
|
||||
g_autoptr(FwupdRequest) request2 = NULL;
|
||||
g_autoptr(GVariant) data = NULL;
|
||||
|
||||
/* create dummy */
|
||||
fwupd_request_set_kind (request, FWUPD_REQUEST_KIND_IMMEDIATE);
|
||||
fwupd_request_set_id (request, FWPUD_REQUEST_ID_REMOVE_REPLUG);
|
||||
fwupd_request_set_message (request, "foo");
|
||||
fwupd_request_set_image (request, "bar");
|
||||
str = fwupd_request_to_string (request);
|
||||
g_debug ("%s", str);
|
||||
|
||||
/* set in init */
|
||||
g_assert_cmpint (fwupd_request_get_created (request), >, 0);
|
||||
|
||||
/* to serialized and back again */
|
||||
data = fwupd_request_to_variant (request);
|
||||
request2 = fwupd_request_from_variant (data);
|
||||
g_assert_cmpint (fwupd_request_get_kind (request2), ==, FWUPD_REQUEST_KIND_IMMEDIATE);
|
||||
g_assert_cmpint (fwupd_request_get_created (request2), >, 0);
|
||||
g_assert_cmpstr (fwupd_request_get_id (request2), ==, FWPUD_REQUEST_ID_REMOVE_REPLUG);
|
||||
g_assert_cmpstr (fwupd_request_get_message (request2), ==, "foo");
|
||||
g_assert_cmpstr (fwupd_request_get_image (request2), ==, "bar");
|
||||
}
|
||||
|
||||
static void
|
||||
fwupd_device_func (void)
|
||||
{
|
||||
@ -714,6 +749,7 @@ main (int argc, char **argv)
|
||||
g_test_add_func ("/fwupd/common{device-id}", fwupd_common_device_id_func);
|
||||
g_test_add_func ("/fwupd/common{guid}", fwupd_common_guid_func);
|
||||
g_test_add_func ("/fwupd/release", fwupd_release_func);
|
||||
g_test_add_func ("/fwupd/request", fwupd_request_func);
|
||||
g_test_add_func ("/fwupd/device", fwupd_device_func);
|
||||
g_test_add_func ("/fwupd/remote{download}", fwupd_remote_download_func);
|
||||
g_test_add_func ("/fwupd/remote{base-uri}", fwupd_remote_baseuri_func);
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include <libfwupd/fwupd-security-attr.h>
|
||||
#include <libfwupd/fwupd-release.h>
|
||||
#include <libfwupd/fwupd-remote.h>
|
||||
#include <libfwupd/fwupd-request.h>
|
||||
#include <libfwupd/fwupd-version.h>
|
||||
|
||||
#ifndef FWUPD_DISABLE_DEPRECATED
|
||||
|
@ -678,5 +678,24 @@ LIBFWUPD_1.6.2 {
|
||||
fwupd_device_has_icon;
|
||||
fwupd_device_remove_child;
|
||||
fwupd_device_set_version_build_date;
|
||||
fwupd_request_from_variant;
|
||||
fwupd_request_get_created;
|
||||
fwupd_request_get_device_id;
|
||||
fwupd_request_get_id;
|
||||
fwupd_request_get_image;
|
||||
fwupd_request_get_kind;
|
||||
fwupd_request_get_message;
|
||||
fwupd_request_get_type;
|
||||
fwupd_request_kind_from_string;
|
||||
fwupd_request_kind_to_string;
|
||||
fwupd_request_new;
|
||||
fwupd_request_set_created;
|
||||
fwupd_request_set_device_id;
|
||||
fwupd_request_set_id;
|
||||
fwupd_request_set_image;
|
||||
fwupd_request_set_kind;
|
||||
fwupd_request_set_message;
|
||||
fwupd_request_to_string;
|
||||
fwupd_request_to_variant;
|
||||
local: *;
|
||||
} LIBFWUPD_1.6.1;
|
||||
|
@ -18,6 +18,7 @@ install_headers([
|
||||
'fwupd-enums.h',
|
||||
'fwupd-error.h',
|
||||
'fwupd-remote.h',
|
||||
'fwupd-request.h',
|
||||
'fwupd-security-attr.h',
|
||||
'fwupd-release.h',
|
||||
'fwupd-plugin.h',
|
||||
@ -48,6 +49,7 @@ libfwupd_src = [
|
||||
'fwupd-release.c', # fuzzing
|
||||
'fwupd-plugin.c',
|
||||
'fwupd-remote.c',
|
||||
'fwupd-request.c', # fuzzing
|
||||
'fwupd-version.c',
|
||||
]
|
||||
|
||||
@ -122,6 +124,9 @@ if get_option('introspection')
|
||||
'fwupd-remote.c',
|
||||
'fwupd-remote.h',
|
||||
'fwupd-remote-private.h',
|
||||
'fwupd-request.c',
|
||||
'fwupd-request.h',
|
||||
'fwupd-request-private.h',
|
||||
'fwupd-version.c',
|
||||
fwupd_version_h,
|
||||
],
|
||||
|
@ -37,6 +37,8 @@ gchar *fu_device_get_guids_as_str (FuDevice *self);
|
||||
GPtrArray *fu_device_get_possible_plugins (FuDevice *self);
|
||||
void fu_device_add_possible_plugin (FuDevice *self,
|
||||
const gchar *plugin);
|
||||
guint fu_device_get_request_cnt (FuDevice *self,
|
||||
FwupdRequestKind request_kind);
|
||||
guint64 fu_device_get_private_flags (FuDevice *self);
|
||||
void fu_device_set_private_flags (FuDevice *self,
|
||||
guint64 flag);
|
||||
|
@ -56,6 +56,7 @@ typedef struct {
|
||||
guint progress;
|
||||
guint battery_level;
|
||||
guint battery_threshold;
|
||||
guint request_cnts[FWUPD_REQUEST_KIND_LAST];
|
||||
gint order;
|
||||
guint priority;
|
||||
guint poll_id;
|
||||
@ -102,6 +103,7 @@ enum {
|
||||
enum {
|
||||
SIGNAL_CHILD_ADDED,
|
||||
SIGNAL_CHILD_REMOVED,
|
||||
SIGNAL_REQUEST,
|
||||
SIGNAL_LAST
|
||||
};
|
||||
|
||||
@ -409,6 +411,27 @@ fu_device_get_private_flags (FuDevice *self)
|
||||
return priv->private_flags;
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_device_get_request_cnt:
|
||||
* @self: a #FuDevice
|
||||
* @request_kind: the type of request
|
||||
*
|
||||
* Returns the number of requests of a specific kind. This function is only
|
||||
* useful to the daemon, which uses it to synthesize artificial events for
|
||||
* plugins not yet ported to [class@FwupdRequest].
|
||||
*
|
||||
* Returns: integer, usually 0
|
||||
*
|
||||
* Since: 1.6.2
|
||||
**/
|
||||
guint
|
||||
fu_device_get_request_cnt (FuDevice *self, FwupdRequestKind request_kind)
|
||||
{
|
||||
FuDevicePrivate *priv = GET_PRIVATE (self);
|
||||
g_return_val_if_fail (FU_IS_DEVICE (self), G_MAXUINT);
|
||||
return priv->request_cnts[request_kind];
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_device_set_private_flags:
|
||||
* @self: a #FuDevice
|
||||
@ -3464,6 +3487,7 @@ fu_device_write_firmware (FuDevice *self,
|
||||
GError **error)
|
||||
{
|
||||
FuDeviceClass *klass = FU_DEVICE_GET_CLASS (self);
|
||||
FuDevicePrivate *priv = GET_PRIVATE (self);
|
||||
g_autoptr(FuFirmware) firmware = NULL;
|
||||
g_autofree gchar *str = NULL;
|
||||
|
||||
@ -3487,7 +3511,23 @@ fu_device_write_firmware (FuDevice *self,
|
||||
g_debug ("installing onto %s:\n%s", fu_device_get_id (self), str);
|
||||
|
||||
/* call vfunc */
|
||||
return klass->write_firmware (self, firmware, flags, error);
|
||||
if (!klass->write_firmware (self, firmware, flags, error))
|
||||
return FALSE;
|
||||
|
||||
/* the device set an UpdateMessage (possibly from a quirk, or XML file)
|
||||
* but did not do an event; guess something */
|
||||
if (priv->request_cnts[FWUPD_REQUEST_KIND_POST] == 0 &&
|
||||
fu_device_get_update_message (self) != NULL) {
|
||||
g_autoptr(FwupdRequest) request = fwupd_request_new ();
|
||||
fwupd_request_set_kind (request, FWUPD_REQUEST_KIND_POST);
|
||||
fwupd_request_set_id (request, FWPUD_REQUEST_ID_REMOVE_REPLUG);
|
||||
fwupd_request_set_message (request, fu_device_get_update_message (self));
|
||||
fwupd_request_set_image (request, fu_device_get_update_image (self));
|
||||
fu_device_emit_request (self, request);
|
||||
}
|
||||
|
||||
/* success */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -4421,6 +4461,47 @@ fu_device_incorporate_from_component (FuDevice *self, XbNode *component)
|
||||
fwupd_device_set_update_image (FWUPD_DEVICE (self), tmp);
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_device_emit_request:
|
||||
* @self: a device
|
||||
* @request: a request
|
||||
*
|
||||
* Emit a request from a plugin to the client.
|
||||
*
|
||||
* Since: 1.6.2
|
||||
**/
|
||||
void
|
||||
fu_device_emit_request (FuDevice *self, FwupdRequest *request)
|
||||
{
|
||||
FuDevicePrivate *priv = GET_PRIVATE (self);
|
||||
|
||||
g_return_if_fail (FU_IS_DEVICE (self));
|
||||
g_return_if_fail (FWUPD_IS_REQUEST (request));
|
||||
|
||||
/* sanity check */
|
||||
if (fwupd_request_get_kind (request) == FWUPD_REQUEST_KIND_UNKNOWN) {
|
||||
g_critical ("a request must have an assigned kind");
|
||||
return;
|
||||
}
|
||||
if (fwupd_request_get_id (request) == NULL) {
|
||||
g_critical ("a request must have an assigned ID");
|
||||
return;
|
||||
}
|
||||
|
||||
/* ensure set */
|
||||
fwupd_request_set_device_id (request, fu_device_get_id (self));
|
||||
|
||||
/* for compatibility with older clients */
|
||||
if (fwupd_request_get_kind (request) == FWUPD_REQUEST_KIND_POST) {
|
||||
fu_device_set_update_message (self, fwupd_request_get_message (request));
|
||||
fu_device_set_update_image (self, fwupd_request_get_image (request));
|
||||
}
|
||||
|
||||
/* proxy to the engine */
|
||||
g_signal_emit (self, signals[SIGNAL_REQUEST], 0, request);
|
||||
priv->request_cnts[fwupd_request_get_kind (request)]++;
|
||||
}
|
||||
|
||||
static void
|
||||
fu_device_class_init (FuDeviceClass *klass)
|
||||
{
|
||||
@ -4442,6 +4523,12 @@ fu_device_class_init (FuDeviceClass *klass)
|
||||
G_STRUCT_OFFSET (FuDeviceClass, child_removed),
|
||||
NULL, NULL, g_cclosure_marshal_VOID__OBJECT,
|
||||
G_TYPE_NONE, 1, FU_TYPE_DEVICE);
|
||||
signals[SIGNAL_REQUEST] =
|
||||
g_signal_new ("request",
|
||||
G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (FuDeviceClass, request),
|
||||
NULL, NULL, g_cclosure_marshal_VOID__OBJECT,
|
||||
G_TYPE_NONE, 1, FWUPD_TYPE_REQUEST);
|
||||
|
||||
pspec = g_param_spec_string ("physical-id", NULL, NULL, NULL,
|
||||
G_PARAM_READWRITE |
|
||||
|
@ -106,8 +106,10 @@ struct _FuDeviceClass
|
||||
FuDevice *child);
|
||||
void (*child_removed) (FuDevice *self, /* signal */
|
||||
FuDevice *child);
|
||||
void (*request) (FuDevice *self, /* signal */
|
||||
FwupdRequest *request);
|
||||
/*< private >*/
|
||||
gpointer padding[7];
|
||||
gpointer padding[6];
|
||||
#endif
|
||||
};
|
||||
|
||||
@ -209,6 +211,8 @@ FuDevice *fu_device_new_with_context (FuContext *ctx);
|
||||
#define fu_device_get_plugin(d) fwupd_device_get_plugin(FWUPD_DEVICE(d))
|
||||
#define fu_device_get_update_error(d) fwupd_device_get_update_error(FWUPD_DEVICE(d))
|
||||
#define fu_device_get_update_state(d) fwupd_device_get_update_state(FWUPD_DEVICE(d))
|
||||
#define fu_device_get_update_message(d) fwupd_device_get_update_message(FWUPD_DEVICE(d))
|
||||
#define fu_device_get_update_image(d) fwupd_device_get_update_image(FWUPD_DEVICE(d))
|
||||
#define fu_device_get_vendor(d) fwupd_device_get_vendor(FWUPD_DEVICE(d))
|
||||
#define fu_device_get_version(d) fwupd_device_get_version(FWUPD_DEVICE(d))
|
||||
#define fu_device_get_version_lowest(d) fwupd_device_get_version_lowest(FWUPD_DEVICE(d))
|
||||
@ -508,3 +512,5 @@ void fu_device_remove_private_flag (FuDevice *self,
|
||||
guint64 flag);
|
||||
gboolean fu_device_has_private_flag (FuDevice *self,
|
||||
guint64 flag);
|
||||
void fu_device_emit_request (FuDevice *self,
|
||||
FwupdRequest *request);
|
||||
|
@ -826,8 +826,10 @@ LIBFWUPDPLUGIN_1.6.2 {
|
||||
fu_device_add_guid_full;
|
||||
fu_device_add_parent_physical_id;
|
||||
fu_device_add_private_flag;
|
||||
fu_device_emit_request;
|
||||
fu_device_get_parent_physical_ids;
|
||||
fu_device_get_private_flags;
|
||||
fu_device_get_request_cnt;
|
||||
fu_device_has_parent_physical_id;
|
||||
fu_device_has_private_flag;
|
||||
fu_device_new_with_context;
|
||||
|
@ -362,32 +362,19 @@ fu_ebitdo_device_setup (FuDevice *device, GError **error)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_ebitdo_device_write_firmware (FuDevice *device,
|
||||
FuFirmware *firmware,
|
||||
FwupdInstallFlags flags,
|
||||
GError **error)
|
||||
fu_ebitdo_device_detach (FuDevice *device, GError **error)
|
||||
{
|
||||
FuEbitdoDevice *self = FU_EBITDO_DEVICE (device);
|
||||
GUsbDevice *usb_device = fu_usb_device_get_dev (FU_USB_DEVICE (device));
|
||||
const guint8 *buf;
|
||||
gsize bufsz = 0;
|
||||
guint32 serial_new[3];
|
||||
g_autoptr(GBytes) fw_hdr = NULL;
|
||||
g_autoptr(GBytes) fw_payload = NULL;
|
||||
g_autoptr(GError) error_local = NULL;
|
||||
g_autoptr(GPtrArray) chunks = NULL;
|
||||
const guint32 app_key_index[16] = {
|
||||
0x186976e5, 0xcac67acd, 0x38f27fee, 0x0a4948f1,
|
||||
0xb75b7753, 0x1f8ffa5c, 0xbff8cf43, 0xc4936167,
|
||||
0x92bd03f0, 0x5573c6ed, 0x57d8845b, 0x827197ac,
|
||||
0xb91901c9, 0x3917edfe, 0xbcd6344f, 0xcf9e23b5
|
||||
};
|
||||
g_autoptr(FwupdRequest) request = fwupd_request_new ();
|
||||
|
||||
/* not in bootloader mode, so print what to do */
|
||||
if (fu_device_has_flag (device, FWUPD_DEVICE_FLAG_NEEDS_BOOTLOADER)) {
|
||||
g_autoptr(GString) msg = g_string_new ("Not in bootloader mode: ");
|
||||
g_string_append (msg, "Disconnect the controller, ");
|
||||
g_print ("1. \n");
|
||||
/* not required */
|
||||
if (fu_device_has_flag (device, FWUPD_DEVICE_FLAG_IS_BOOTLOADER))
|
||||
return TRUE;
|
||||
|
||||
/* generate a message if not already set from the metadata */
|
||||
if (fu_device_get_update_message (device) == NULL) {
|
||||
GUsbDevice *usb_device = fu_usb_device_get_dev (FU_USB_DEVICE (device));
|
||||
g_autoptr(GString) msg = g_string_new (NULL);
|
||||
g_string_append (msg, "Not in bootloader mode: Disconnect the controller, ");
|
||||
switch (g_usb_device_get_pid (usb_device)) {
|
||||
case 0xab11: /* FC30 */
|
||||
case 0xab12: /* NES30 */
|
||||
@ -428,10 +415,49 @@ fu_ebitdo_device_write_firmware (FuDevice *device,
|
||||
break;
|
||||
}
|
||||
g_string_append (msg, "then re-connect controller");
|
||||
fu_device_set_update_message (device, msg->str);
|
||||
}
|
||||
|
||||
/* wait */
|
||||
fu_device_set_progress (device, 0);
|
||||
fu_device_add_flag (device, FWUPD_DEVICE_FLAG_WAIT_FOR_REPLUG);
|
||||
|
||||
/* emit request */
|
||||
fwupd_request_set_kind (request, FWUPD_REQUEST_KIND_IMMEDIATE);
|
||||
fwupd_request_set_id (request, FWPUD_REQUEST_ID_REMOVE_REPLUG);
|
||||
fwupd_request_set_message (request, fu_device_get_update_message (device));
|
||||
fwupd_request_set_image (request, fu_device_get_update_image (device));
|
||||
fu_device_emit_request (device, request);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_ebitdo_device_write_firmware (FuDevice *device,
|
||||
FuFirmware *firmware,
|
||||
FwupdInstallFlags flags,
|
||||
GError **error)
|
||||
{
|
||||
FuEbitdoDevice *self = FU_EBITDO_DEVICE (device);
|
||||
const guint8 *buf;
|
||||
gsize bufsz = 0;
|
||||
guint32 serial_new[3];
|
||||
g_autoptr(GBytes) fw_hdr = NULL;
|
||||
g_autoptr(GBytes) fw_payload = NULL;
|
||||
g_autoptr(GError) error_local = NULL;
|
||||
g_autoptr(GPtrArray) chunks = NULL;
|
||||
const guint32 app_key_index[16] = {
|
||||
0x186976e5, 0xcac67acd, 0x38f27fee, 0x0a4948f1,
|
||||
0xb75b7753, 0x1f8ffa5c, 0xbff8cf43, 0xc4936167,
|
||||
0x92bd03f0, 0x5573c6ed, 0x57d8845b, 0x827197ac,
|
||||
0xb91901c9, 0x3917edfe, 0xbcd6344f, 0xcf9e23b5
|
||||
};
|
||||
|
||||
/* not in bootloader mode */
|
||||
if (!fu_device_has_flag (device, FWUPD_DEVICE_FLAG_IS_BOOTLOADER)) {
|
||||
g_set_error_literal (error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_NEEDS_USER_ACTION,
|
||||
msg->str);
|
||||
"Not in bootloader mode");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -586,7 +612,6 @@ fu_ebitdo_device_probe (FuDevice *device, GError **error)
|
||||
if (!fu_device_has_flag (device, FWUPD_DEVICE_FLAG_IS_BOOTLOADER)) {
|
||||
fu_device_add_counterpart_guid (device, "USB\\VID_0483&PID_5750");
|
||||
fu_device_add_counterpart_guid (device, "USB\\VID_2DC8&PID_5750");
|
||||
fu_device_add_flag (device, FWUPD_DEVICE_FLAG_NEEDS_BOOTLOADER);
|
||||
}
|
||||
|
||||
/* success */
|
||||
@ -619,6 +644,7 @@ fu_ebitdo_device_class_init (FuEbitdoDeviceClass *klass)
|
||||
FuDeviceClass *klass_device = FU_DEVICE_CLASS (klass);
|
||||
klass_device->write_firmware = fu_ebitdo_device_write_firmware;
|
||||
klass_device->setup = fu_ebitdo_device_setup;
|
||||
klass_device->detach = fu_ebitdo_device_detach;
|
||||
klass_device->attach = fu_ebitdo_device_attach;
|
||||
klass_device->open = fu_ebitdo_device_open;
|
||||
klass_device->probe = fu_ebitdo_device_probe;
|
||||
|
@ -96,31 +96,65 @@ fu_system76_launch_device_setup (FuDevice *device, GError **error)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_system76_launch_device_detach (FuDevice *device, GError **error)
|
||||
fu_system76_launch_device_reset (FuDevice *device, guint8 *rc, GError **error)
|
||||
{
|
||||
guint8 data[32] = { 0 };
|
||||
guint8 data[32] = { SYSTEM76_LAUNCH_CMD_RESET, 0 };
|
||||
|
||||
/* execute reset command */
|
||||
data[0] = SYSTEM76_LAUNCH_CMD_RESET;
|
||||
if (!fu_system76_launch_device_command (device, data, sizeof(data), error)) {
|
||||
g_prefix_error (error, "failed to execute reset command: ");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*rc = data[1];
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_system76_launch_device_detach (FuDevice *device, GError **error)
|
||||
{
|
||||
guint8 rc = 0x0;
|
||||
g_autoptr(FwupdRequest) request = fwupd_request_new ();
|
||||
g_autoptr(GTimer) timer = g_timer_new ();
|
||||
|
||||
/* prompt for unlock if reset was blocked */
|
||||
if (data[1] != 0) {
|
||||
g_set_error (error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_NEEDS_USER_ACTION,
|
||||
"To ensure you have physical access, %s needs to be manually unlocked. "
|
||||
if (!fu_system76_launch_device_reset (device, &rc, error))
|
||||
return FALSE;
|
||||
|
||||
/* unlikely, but already unlocked */
|
||||
if (rc == 0)
|
||||
return TRUE;
|
||||
|
||||
/* generate a message if not already set */
|
||||
if (fu_device_get_update_message (device) == NULL) {
|
||||
g_autofree gchar *msg = NULL;
|
||||
msg = g_strdup_printf ("To ensure you have physical access, %s needs to be manually unlocked. "
|
||||
"Please press Fn+Esc to unlock and re-run the update.",
|
||||
fu_device_get_name (device));
|
||||
return FALSE;
|
||||
fu_device_set_update_message (device, msg);
|
||||
}
|
||||
|
||||
fu_device_set_status (device, FWUPD_STATUS_DEVICE_RESTART);
|
||||
fu_device_add_flag (device, FWUPD_DEVICE_FLAG_WAIT_FOR_REPLUG);
|
||||
/* the user has to do something */
|
||||
fwupd_request_set_kind (request, FWUPD_REQUEST_KIND_IMMEDIATE);
|
||||
fwupd_request_set_id (request, FWPUD_REQUEST_ID_PRESS_UNLOCK);
|
||||
fwupd_request_set_message (request, fu_device_get_update_message (device));
|
||||
fu_device_emit_request (device, request);
|
||||
|
||||
/* poll for the user-unlock */
|
||||
fu_device_set_progress (device, 0);
|
||||
do {
|
||||
g_usleep (G_USEC_PER_SEC);
|
||||
if (!fu_system76_launch_device_reset (device, &rc, error))
|
||||
return FALSE;
|
||||
} while (rc != 0 &&
|
||||
g_timer_elapsed (timer, NULL) * 1000.f < FU_DEVICE_REMOVE_DELAY_USER_REPLUG);
|
||||
if (rc != 0) {
|
||||
g_set_error_literal (error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_NEEDS_USER_ACTION,
|
||||
fu_device_get_update_message (device));
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
112
src/fu-engine.c
112
src/fu-engine.c
@ -121,6 +121,7 @@ enum {
|
||||
SIGNAL_DEVICE_ADDED,
|
||||
SIGNAL_DEVICE_REMOVED,
|
||||
SIGNAL_DEVICE_CHANGED,
|
||||
SIGNAL_DEVICE_REQUEST,
|
||||
SIGNAL_STATUS_CHANGED,
|
||||
SIGNAL_PERCENTAGE_CHANGED,
|
||||
SIGNAL_LAST
|
||||
@ -221,6 +222,14 @@ fu_engine_generic_notify_cb (FuDevice *device, GParamSpec *pspec, FuEngine *self
|
||||
fu_engine_emit_device_changed (self, device);
|
||||
}
|
||||
|
||||
static void
|
||||
fu_engine_device_request_cb (FuDevice *device, FwupdRequest *request, FuEngine *self)
|
||||
{
|
||||
g_debug ("Emitting DeviceRequest('Message'='%s')",
|
||||
fwupd_request_get_message (request));
|
||||
g_signal_emit (self, signals[SIGNAL_DEVICE_REQUEST], 0, request);
|
||||
}
|
||||
|
||||
static void
|
||||
fu_engine_watch_device (FuEngine *self, FuDevice *device)
|
||||
{
|
||||
@ -232,6 +241,9 @@ fu_engine_watch_device (FuEngine *self, FuDevice *device)
|
||||
g_signal_handlers_disconnect_by_func (device_old,
|
||||
fu_engine_status_notify_cb,
|
||||
self);
|
||||
g_signal_handlers_disconnect_by_func (device_old,
|
||||
fu_engine_device_request_cb,
|
||||
self);
|
||||
}
|
||||
g_signal_connect (device, "notify::progress",
|
||||
G_CALLBACK (fu_engine_progress_notify_cb), self);
|
||||
@ -243,6 +255,8 @@ fu_engine_watch_device (FuEngine *self, FuDevice *device)
|
||||
G_CALLBACK (fu_engine_generic_notify_cb), self);
|
||||
g_signal_connect (device, "notify::update-image",
|
||||
G_CALLBACK (fu_engine_generic_notify_cb), self);
|
||||
g_signal_connect (device, "request",
|
||||
G_CALLBACK (fu_engine_device_request_cb), self);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -2046,6 +2060,7 @@ fu_engine_install_tasks (FuEngine *self,
|
||||
FwupdInstallFlags flags,
|
||||
GError **error)
|
||||
{
|
||||
FwupdFeatureFlags feature_flags = fu_engine_request_get_feature_flags (request);
|
||||
g_autoptr(FuIdleLocker) locker = NULL;
|
||||
g_autoptr(GPtrArray) devices = NULL;
|
||||
g_autoptr(GPtrArray) devices_new = NULL;
|
||||
@ -2070,7 +2085,9 @@ fu_engine_install_tasks (FuEngine *self,
|
||||
/* all authenticated, so install all the things */
|
||||
for (guint i = 0; i < install_tasks->len; i++) {
|
||||
FuInstallTask *task = g_ptr_array_index (install_tasks, i);
|
||||
if (!fu_engine_install (self, task, blob_cab, flags, error)) {
|
||||
if (!fu_engine_install (self, task, blob_cab,
|
||||
flags, feature_flags,
|
||||
error)) {
|
||||
g_autoptr(GError) error_local = NULL;
|
||||
if (!fu_engine_composite_cleanup (self, devices, &error_local)) {
|
||||
g_warning ("failed to cleanup failed composite action: %s",
|
||||
@ -2332,6 +2349,7 @@ fu_engine_install_release (FuEngine *self,
|
||||
XbNode *component,
|
||||
XbNode *rel,
|
||||
FwupdInstallFlags flags,
|
||||
FwupdFeatureFlags feature_flags,
|
||||
GError **error)
|
||||
{
|
||||
FuPlugin *plugin;
|
||||
@ -2402,7 +2420,9 @@ fu_engine_install_release (FuEngine *self,
|
||||
|
||||
/* install firmware blob */
|
||||
version_orig = g_strdup (fu_device_get_version (device));
|
||||
if (!fu_engine_install_blob (self, device, blob_fw2, flags, &error_local)) {
|
||||
if (!fu_engine_install_blob (self, device, blob_fw2,
|
||||
flags, feature_flags,
|
||||
&error_local)) {
|
||||
fu_device_set_status (device, FWUPD_STATUS_IDLE);
|
||||
if (g_error_matches (error_local,
|
||||
FWUPD_ERROR,
|
||||
@ -2527,6 +2547,7 @@ fu_engine_sort_releases (FuEngine *self, FuDevice *device, GPtrArray *rels, GErr
|
||||
* @task: a #FuInstallTask
|
||||
* @blob_cab: the #GBytes of the .cab file
|
||||
* @flags: install flags, e.g. %FWUPD_INSTALL_FLAG_ALLOW_OLDER
|
||||
* @feature_flags: feature flags, e.g. %FWUPD_FEATURE_FLAG_NONE
|
||||
* @error: (nullable): optional return location for an error
|
||||
*
|
||||
* Installs a specific firmware file on a device.
|
||||
@ -2542,6 +2563,7 @@ fu_engine_install (FuEngine *self,
|
||||
FuInstallTask *task,
|
||||
GBytes *blob_cab,
|
||||
FwupdInstallFlags flags,
|
||||
FwupdFeatureFlags feature_flags,
|
||||
GError **error)
|
||||
{
|
||||
XbNode *component = fu_install_task_get_component (task);
|
||||
@ -2559,28 +2581,16 @@ fu_engine_install (FuEngine *self,
|
||||
|
||||
/* not in bootloader mode */
|
||||
device = g_object_ref (fu_install_task_get_device (task));
|
||||
if (fu_device_has_flag (device, FWUPD_DEVICE_FLAG_NEEDS_BOOTLOADER)) {
|
||||
const gchar *caption = NULL;
|
||||
caption = xb_node_query_text (component,
|
||||
"screenshots/screenshot/caption",
|
||||
NULL);
|
||||
if (caption != NULL) {
|
||||
g_set_error (error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_NEEDS_USER_ACTION,
|
||||
"Device %s needs to manually be put in update mode: %s",
|
||||
fu_device_get_name (device), caption);
|
||||
} else {
|
||||
g_set_error (error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_NEEDS_USER_ACTION,
|
||||
"Device %s needs to manually be put in update mode",
|
||||
fu_device_get_name (device));
|
||||
}
|
||||
fu_device_set_update_state (device, FWUPD_UPDATE_STATE_FAILED_TRANSIENT);
|
||||
if (error != NULL)
|
||||
fu_device_set_update_error (device, (*error)->message);
|
||||
return FALSE;
|
||||
if (!fu_device_has_flag (device, FWUPD_DEVICE_FLAG_IS_BOOTLOADER)) {
|
||||
const gchar *tmp = NULL;
|
||||
|
||||
/* both optional; the plugin can specify a fallback */
|
||||
tmp = xb_node_query_text (component, "screenshots/screenshot/caption", NULL);
|
||||
if (tmp != NULL)
|
||||
fu_device_set_update_message (device, tmp);
|
||||
tmp = xb_node_query_text (component, "screenshots/screenshot/image", NULL);
|
||||
if (tmp != NULL)
|
||||
fu_device_set_update_image (device, tmp);
|
||||
}
|
||||
|
||||
/* get the newest version */
|
||||
@ -2649,11 +2659,23 @@ fu_engine_install (FuEngine *self,
|
||||
return FALSE;
|
||||
for (guint i = 0; i < rels->len; i++) {
|
||||
XbNode *rel = g_ptr_array_index (rels, i);
|
||||
if (!fu_engine_install_release (self, device, component, rel, flags, error))
|
||||
if (!fu_engine_install_release (self,
|
||||
device,
|
||||
component,
|
||||
rel,
|
||||
flags,
|
||||
feature_flags,
|
||||
error))
|
||||
return FALSE;
|
||||
}
|
||||
} else {
|
||||
if (!fu_engine_install_release (self, device, component, rel_newest, flags, error))
|
||||
if (!fu_engine_install_release (self,
|
||||
device,
|
||||
component,
|
||||
rel_newest,
|
||||
flags,
|
||||
feature_flags,
|
||||
error))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -2829,7 +2851,10 @@ fu_engine_update_cleanup (FuEngine *self,
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_engine_update_detach (FuEngine *self, const gchar *device_id, GError **error)
|
||||
fu_engine_update_detach (FuEngine *self,
|
||||
const gchar *device_id,
|
||||
FwupdFeatureFlags feature_flags,
|
||||
GError **error)
|
||||
{
|
||||
FuPlugin *plugin;
|
||||
g_autofree gchar *str = NULL;
|
||||
@ -2848,6 +2873,29 @@ fu_engine_update_detach (FuEngine *self, const gchar *device_id, GError **error)
|
||||
return FALSE;
|
||||
if (!fu_plugin_runner_update_detach (plugin, device, error))
|
||||
return FALSE;
|
||||
|
||||
/* support older clients without the ability to do immediate requests */
|
||||
if ((feature_flags & FWUPD_FEATURE_FLAG_REQUESTS) == 0 &&
|
||||
fu_device_get_request_cnt (device, FWUPD_REQUEST_KIND_IMMEDIATE) > 0) {
|
||||
|
||||
/* fallback to something sane */
|
||||
if (fu_device_get_update_message (device) == NULL) {
|
||||
g_autofree gchar *tmp = NULL;
|
||||
tmp = g_strdup_printf ("Device %s needs to manually be put in update mode",
|
||||
fu_device_get_name (device));
|
||||
fu_device_set_update_message (device, tmp);
|
||||
}
|
||||
|
||||
/* abort and require client to re-submit */
|
||||
fu_device_remove_flag (device, FWUPD_DEVICE_FLAG_WAIT_FOR_REPLUG);
|
||||
g_set_error_literal (error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_NEEDS_USER_ACTION,
|
||||
fu_device_get_update_message (device));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* success */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -3043,6 +3091,7 @@ fu_engine_install_blob (FuEngine *self,
|
||||
FuDevice *device,
|
||||
GBytes *blob_fw,
|
||||
FwupdInstallFlags flags,
|
||||
FwupdFeatureFlags feature_flags,
|
||||
GError **error)
|
||||
{
|
||||
guint retries = 0;
|
||||
@ -3081,7 +3130,7 @@ fu_engine_install_blob (FuEngine *self,
|
||||
return FALSE;
|
||||
|
||||
/* detach to bootloader mode */
|
||||
if (!fu_engine_update_detach (self, device_id, error))
|
||||
if (!fu_engine_update_detach (self, device_id, feature_flags, error))
|
||||
return FALSE;
|
||||
|
||||
/* install */
|
||||
@ -4681,7 +4730,7 @@ fu_engine_add_releases_for_device_component (FuEngine *self,
|
||||
update_message = fwupd_release_get_update_message (rel);
|
||||
if (fwupd_device_get_update_message (FWUPD_DEVICE (device)) == NULL &&
|
||||
update_message != NULL) {
|
||||
fwupd_device_set_update_message (FWUPD_DEVICE (device), update_message);
|
||||
fu_device_set_update_message (device, update_message);
|
||||
}
|
||||
update_image = fwupd_release_get_update_image (rel);
|
||||
if (fwupd_device_get_update_image (FWUPD_DEVICE (device)) == NULL &&
|
||||
@ -6656,6 +6705,11 @@ fu_engine_class_init (FuEngineClass *klass)
|
||||
G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
|
||||
0, NULL, NULL, g_cclosure_marshal_VOID__OBJECT,
|
||||
G_TYPE_NONE, 1, FU_TYPE_DEVICE);
|
||||
signals[SIGNAL_DEVICE_REQUEST] =
|
||||
g_signal_new ("device-request",
|
||||
G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
|
||||
0, NULL, NULL, g_cclosure_marshal_VOID__OBJECT,
|
||||
G_TYPE_NONE, 1, FWUPD_TYPE_REQUEST);
|
||||
signals[SIGNAL_STATUS_CHANGED] =
|
||||
g_signal_new ("status-changed",
|
||||
G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
|
||||
|
@ -146,11 +146,13 @@ gboolean fu_engine_install (FuEngine *self,
|
||||
FuInstallTask *task,
|
||||
GBytes *blob_cab,
|
||||
FwupdInstallFlags flags,
|
||||
FwupdFeatureFlags feature_flags,
|
||||
GError **error);
|
||||
gboolean fu_engine_install_blob (FuEngine *self,
|
||||
FuDevice *device,
|
||||
GBytes *blob_fw,
|
||||
FwupdInstallFlags flags,
|
||||
FwupdFeatureFlags feature_flags,
|
||||
GError **error);
|
||||
gboolean fu_engine_install_tasks (FuEngine *self,
|
||||
FuEngineRequest *request,
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include "fwupd-security-attr-private.h"
|
||||
#include "fwupd-release-private.h"
|
||||
#include "fwupd-remote-private.h"
|
||||
#include "fwupd-request-private.h"
|
||||
#include "fwupd-resources.h"
|
||||
|
||||
#include "fu-common.h"
|
||||
@ -161,6 +162,25 @@ fu_main_engine_device_changed_cb (FuEngine *engine,
|
||||
g_variant_new_tuple (&val, 1), NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
fu_main_engine_device_request_cb (FuEngine *engine,
|
||||
FwupdRequest *request,
|
||||
FuMainPrivate *priv)
|
||||
{
|
||||
GVariant *val;
|
||||
|
||||
/* not yet connected */
|
||||
if (priv->connection == NULL)
|
||||
return;
|
||||
val = fwupd_request_to_variant (FWUPD_REQUEST (request));
|
||||
g_dbus_connection_emit_signal (priv->connection,
|
||||
NULL,
|
||||
FWUPD_DBUS_PATH,
|
||||
FWUPD_DBUS_INTERFACE,
|
||||
"DeviceRequest",
|
||||
g_variant_new_tuple (&val, 1), NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
fu_main_emit_property_changed (FuMainPrivate *priv,
|
||||
const gchar *property_name,
|
||||
@ -1939,6 +1959,9 @@ main (int argc, char *argv[])
|
||||
g_signal_connect (priv->engine, "device-changed",
|
||||
G_CALLBACK (fu_main_engine_device_changed_cb),
|
||||
priv);
|
||||
g_signal_connect (priv->engine, "device-request",
|
||||
G_CALLBACK (fu_main_engine_device_request_cb),
|
||||
priv);
|
||||
g_signal_connect (priv->engine, "status-changed",
|
||||
G_CALLBACK (fu_main_engine_status_changed_cb),
|
||||
priv);
|
||||
|
@ -1734,7 +1734,9 @@ fu_engine_history_func (gconstpointer user_data)
|
||||
/* install it */
|
||||
task = fu_install_task_new (device, component);
|
||||
ret = fu_engine_install (engine, task, blob_cab,
|
||||
FWUPD_INSTALL_FLAG_NONE, &error);
|
||||
FWUPD_INSTALL_FLAG_NONE,
|
||||
FWUPD_FEATURE_FLAG_NONE,
|
||||
&error);
|
||||
g_assert_no_error (error);
|
||||
g_assert (ret);
|
||||
|
||||
@ -1857,7 +1859,9 @@ fu_engine_multiple_rels_func (gconstpointer user_data)
|
||||
/* install it */
|
||||
task = fu_install_task_new (device, component);
|
||||
ret = fu_engine_install (engine, task, blob_cab,
|
||||
FWUPD_INSTALL_FLAG_NONE, &error);
|
||||
FWUPD_INSTALL_FLAG_NONE,
|
||||
FWUPD_FEATURE_FLAG_NONE,
|
||||
&error);
|
||||
g_assert_no_error (error);
|
||||
g_assert (ret);
|
||||
|
||||
@ -1930,7 +1934,9 @@ fu_engine_history_inherit (gconstpointer user_data)
|
||||
g_setenv ("FWUPD_PLUGIN_TEST", "requires-activation", TRUE);
|
||||
task = fu_install_task_new (device, component);
|
||||
ret = fu_engine_install (engine, task, blob_cab,
|
||||
FWUPD_INSTALL_FLAG_NONE, &error);
|
||||
FWUPD_INSTALL_FLAG_NONE,
|
||||
FWUPD_FEATURE_FLAG_NONE,
|
||||
&error);
|
||||
g_assert_no_error (error);
|
||||
g_assert (ret);
|
||||
|
||||
@ -1951,7 +1957,9 @@ fu_engine_history_inherit (gconstpointer user_data)
|
||||
fu_device_set_version_format (device, FWUPD_VERSION_FORMAT_TRIPLET);
|
||||
fu_device_set_version (device, "1.2.2");
|
||||
ret = fu_engine_install (engine, task, blob_cab,
|
||||
FWUPD_INSTALL_FLAG_NONE, &error);
|
||||
FWUPD_INSTALL_FLAG_NONE,
|
||||
FWUPD_FEATURE_FLAG_NONE,
|
||||
&error);
|
||||
g_assert_no_error (error);
|
||||
g_assert (ret);
|
||||
g_object_unref (engine);
|
||||
@ -2057,7 +2065,9 @@ fu_engine_history_error_func (gconstpointer user_data)
|
||||
g_assert_nonnull (component);
|
||||
task = fu_install_task_new (device, component);
|
||||
ret = fu_engine_install (engine, task, blob_cab,
|
||||
FWUPD_INSTALL_FLAG_NONE, &error);
|
||||
FWUPD_INSTALL_FLAG_NONE,
|
||||
FWUPD_FEATURE_FLAG_NONE,
|
||||
&error);
|
||||
g_assert_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED);
|
||||
g_assert (error != NULL);
|
||||
g_assert_cmpstr (error->message, ==,
|
||||
@ -2796,7 +2806,9 @@ fu_plugin_module_func (gconstpointer user_data)
|
||||
fu_engine_add_device (engine, device);
|
||||
fu_engine_add_plugin (engine, self->plugin);
|
||||
ret = fu_engine_install_blob (engine, device, blob_cab,
|
||||
FWUPD_INSTALL_FLAG_NONE, &error);
|
||||
FWUPD_INSTALL_FLAG_NONE,
|
||||
FWUPD_FEATURE_FLAG_NONE,
|
||||
&error);
|
||||
g_assert_no_error (error);
|
||||
g_assert (ret);
|
||||
g_assert_cmpint (cnt, ==, 4);
|
||||
|
@ -878,7 +878,10 @@ fu_util_install_blob (FuUtilPrivate *priv, gchar **values, GError **error)
|
||||
}
|
||||
}
|
||||
priv->flags |= FWUPD_INSTALL_FLAG_NO_HISTORY;
|
||||
if (!fu_engine_install_blob (priv->engine, device, blob_fw, priv->flags, error))
|
||||
if (!fu_engine_install_blob (priv->engine, device, blob_fw,
|
||||
priv->flags,
|
||||
fu_engine_request_get_feature_flags (priv->request),
|
||||
error))
|
||||
return FALSE;
|
||||
if (priv->cleanup_blob) {
|
||||
g_autoptr(FuDevice) device_new = NULL;
|
||||
|
@ -66,7 +66,7 @@ struct FuUtilPrivate {
|
||||
/* only valid in update and downgrade */
|
||||
FuUtilOperation current_operation;
|
||||
FwupdDevice *current_device;
|
||||
gchar *current_message;
|
||||
GPtrArray *post_requests;
|
||||
FwupdDeviceFlags completion_flags;
|
||||
FwupdDeviceFlags filter_include;
|
||||
FwupdDeviceFlags filter_exclude;
|
||||
@ -84,6 +84,32 @@ fu_util_client_notify_cb (GObject *object,
|
||||
fwupd_client_get_percentage (priv->client));
|
||||
}
|
||||
|
||||
static void
|
||||
fu_util_update_device_request_cb (FwupdClient *client,
|
||||
FwupdRequest *request,
|
||||
FuUtilPrivate *priv)
|
||||
{
|
||||
/* nothing sensible to show */
|
||||
if (fwupd_request_get_message (request) == NULL)
|
||||
return;
|
||||
|
||||
/* show this now */
|
||||
if (fwupd_request_get_kind (request) == FWUPD_REQUEST_KIND_IMMEDIATE) {
|
||||
g_autofree gchar *fmt = NULL;
|
||||
g_autofree gchar *tmp = NULL;
|
||||
|
||||
/* TRANSLATORS: the user needs to do something, e.g. remove the device */
|
||||
fmt = fu_util_term_format (_("Action Required:"), FU_UTIL_TERM_COLOR_RED);
|
||||
tmp = g_strdup_printf ("%s %s", fmt,
|
||||
fwupd_request_get_message (request));
|
||||
fu_progressbar_set_title (priv->progressbar, tmp);
|
||||
}
|
||||
|
||||
/* save for later */
|
||||
if (fwupd_request_get_kind (request) == FWUPD_REQUEST_KIND_POST)
|
||||
g_ptr_array_add (priv->post_requests, g_object_ref (request));
|
||||
}
|
||||
|
||||
static void
|
||||
fu_util_update_device_changed_cb (FwupdClient *client,
|
||||
FwupdDevice *device,
|
||||
@ -131,12 +157,6 @@ fu_util_update_device_changed_cb (FwupdClient *client,
|
||||
g_warning ("no FuUtilOperation set");
|
||||
}
|
||||
g_set_object (&priv->current_device, device);
|
||||
|
||||
if (priv->current_message == NULL) {
|
||||
const gchar *tmp = fwupd_device_get_update_message (priv->current_device);
|
||||
if (tmp != NULL)
|
||||
priv->current_message = g_strdup (tmp);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -551,14 +571,14 @@ fu_util_download_if_required (FuUtilPrivate *priv, const gchar *perhapsfn, GErro
|
||||
static void
|
||||
fu_util_display_current_message (FuUtilPrivate *priv)
|
||||
{
|
||||
if (priv->current_message == NULL) {
|
||||
/* TRANSLATORS: success message */
|
||||
g_print ("%s\n", _("Successfully installed firmware"));
|
||||
return;
|
||||
|
||||
/* print all POST requests */
|
||||
for (guint i = 0; i < priv->post_requests->len; i++) {
|
||||
FwupdRequest *request = g_ptr_array_index (priv->post_requests, i);
|
||||
g_print ("%s\n", fwupd_request_get_message (request));
|
||||
}
|
||||
/* TRANSLATORS: success message */
|
||||
g_print ("%s: %s\n", _("Successfully installed firmware"), priv->current_message);
|
||||
g_clear_pointer (&priv->current_message, g_free);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -583,6 +603,8 @@ fu_util_install (FuUtilPrivate *priv, gchar **values, GError **error)
|
||||
priv->current_operation = FU_UTIL_OPERATION_INSTALL;
|
||||
g_signal_connect (priv->client, "device-changed",
|
||||
G_CALLBACK (fu_util_update_device_changed_cb), priv);
|
||||
g_signal_connect (priv->client, "device-request",
|
||||
G_CALLBACK (fu_util_update_device_request_cb), priv);
|
||||
|
||||
/* install with flags chosen by the user */
|
||||
filename = fu_util_download_if_required (priv, values[0], error);
|
||||
@ -1581,6 +1603,8 @@ fu_util_update_all (FuUtilPrivate *priv, GError **error)
|
||||
priv->current_operation = FU_UTIL_OPERATION_UPDATE;
|
||||
g_signal_connect (priv->client, "device-changed",
|
||||
G_CALLBACK (fu_util_update_device_changed_cb), priv);
|
||||
g_signal_connect (priv->client, "device-request",
|
||||
G_CALLBACK (fu_util_update_device_request_cb), priv);
|
||||
g_ptr_array_sort (devices, fu_util_sort_devices_by_flags_cb);
|
||||
for (guint i = 0; i < devices->len; i++) {
|
||||
FwupdDevice *dev = g_ptr_array_index (devices, i);
|
||||
@ -1667,6 +1691,8 @@ fu_util_update_by_id (FuUtilPrivate *priv, const gchar *device_id, GError **erro
|
||||
priv->current_operation = FU_UTIL_OPERATION_UPDATE;
|
||||
g_signal_connect (priv->client, "device-changed",
|
||||
G_CALLBACK (fu_util_update_device_changed_cb), priv);
|
||||
g_signal_connect (priv->client, "device-request",
|
||||
G_CALLBACK (fu_util_update_device_request_cb), priv);
|
||||
|
||||
/* get the releases for this device and filter for validity */
|
||||
rels = fwupd_client_get_upgrades (priv->client,
|
||||
@ -1874,6 +1900,8 @@ fu_util_downgrade (FuUtilPrivate *priv, gchar **values, GError **error)
|
||||
priv->current_operation = FU_UTIL_OPERATION_DOWNGRADE;
|
||||
g_signal_connect (priv->client, "device-changed",
|
||||
G_CALLBACK (fu_util_update_device_changed_cb), priv);
|
||||
g_signal_connect (priv->client, "device-request",
|
||||
G_CALLBACK (fu_util_update_device_request_cb), priv);
|
||||
priv->flags |= FWUPD_INSTALL_FLAG_ALLOW_OLDER;
|
||||
if (!fu_util_update_device_with_release (priv, dev, rel, error))
|
||||
return FALSE;
|
||||
@ -1935,6 +1963,8 @@ fu_util_reinstall (FuUtilPrivate *priv, gchar **values, GError **error)
|
||||
priv->current_operation = FU_UTIL_OPERATION_INSTALL;
|
||||
g_signal_connect (priv->client, "device-changed",
|
||||
G_CALLBACK (fu_util_update_device_changed_cb), priv);
|
||||
g_signal_connect (priv->client, "device-request",
|
||||
G_CALLBACK (fu_util_update_device_request_cb), priv);
|
||||
priv->flags |= FWUPD_INSTALL_FLAG_ALLOW_REINSTALL;
|
||||
if (!fu_util_update_device_with_release (priv, dev, rel, error))
|
||||
return FALSE;
|
||||
@ -2059,6 +2089,8 @@ fu_util_switch_branch (FuUtilPrivate *priv, gchar **values, GError **error)
|
||||
priv->current_operation = FU_UTIL_OPERATION_INSTALL;
|
||||
g_signal_connect (priv->client, "device-changed",
|
||||
G_CALLBACK (fu_util_update_device_changed_cb), priv);
|
||||
g_signal_connect (priv->client, "device-request",
|
||||
G_CALLBACK (fu_util_update_device_request_cb), priv);
|
||||
priv->flags |= FWUPD_INSTALL_FLAG_ALLOW_REINSTALL;
|
||||
priv->flags |= FWUPD_INSTALL_FLAG_ALLOW_BRANCH_SWITCH;
|
||||
if (!fu_util_update_device_with_release (priv, dev, rel, error))
|
||||
@ -2485,7 +2517,7 @@ fu_util_private_free (FuUtilPrivate *priv)
|
||||
g_object_unref (priv->client);
|
||||
if (priv->current_device != NULL)
|
||||
g_object_unref (priv->current_device);
|
||||
g_free (priv->current_message);
|
||||
g_ptr_array_unref (priv->post_requests);
|
||||
g_main_context_unref (priv->main_ctx);
|
||||
g_object_unref (priv->cancellable);
|
||||
g_object_unref (priv->progressbar);
|
||||
@ -2852,6 +2884,7 @@ main (int argc, char *argv[])
|
||||
/* create helper object */
|
||||
priv->main_ctx = g_main_context_new ();
|
||||
priv->progressbar = fu_progressbar_new ();
|
||||
priv->post_requests = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
|
||||
fu_progressbar_set_main_context (priv->progressbar, priv->main_ctx);
|
||||
|
||||
/* add commands */
|
||||
@ -3267,6 +3300,7 @@ main (int argc, char *argv[])
|
||||
if (!fwupd_client_set_feature_flags (priv->client,
|
||||
FWUPD_FEATURE_FLAG_CAN_REPORT |
|
||||
FWUPD_FEATURE_FLAG_SWITCH_BRANCH |
|
||||
FWUPD_FEATURE_FLAG_REQUESTS |
|
||||
FWUPD_FEATURE_FLAG_UPDATE_ACTION |
|
||||
FWUPD_FEATURE_FLAG_DETACH_ACTION,
|
||||
priv->cancellable, &error)) {
|
||||
|
@ -831,5 +831,23 @@
|
||||
</doc:doc>
|
||||
</signal>
|
||||
|
||||
<!--***********************************************************-->
|
||||
<signal name='DeviceRequest'>
|
||||
<arg type='a{sv}' name='request' direction='out'>
|
||||
<doc:doc>
|
||||
<doc:summary>
|
||||
<doc:para>A device request.</doc:para>
|
||||
</doc:summary>
|
||||
</doc:doc>
|
||||
</arg>
|
||||
<doc:doc>
|
||||
<doc:description>
|
||||
<doc:para>
|
||||
A device request to the client.
|
||||
</doc:para>
|
||||
</doc:description>
|
||||
</doc:doc>
|
||||
</signal>
|
||||
|
||||
</interface>
|
||||
</node>
|
||||
|
Loading…
Reference in New Issue
Block a user