Commit 893e476c authored by Simon McVittie's avatar Simon McVittie
Browse files

Update upstream source from tag 'upstream/3.38.2'

Update to upstream version '3.38.2'
with Debian dir 2f42606ff26e5be120959ed913482debae7ed06c
parents 212085ae 987e0247
==============
Version 3.38.2
==============
rfkill:
- Fix reading /dev/rfkill on newer kernels
housekeeping:
- Fix crash when atime is not present #556
power:
- Avoid automatic logout when inappropriate (greeter session)
- Only one warn once when the battery of external devices runs low #108
usb-protection:
- Do not warn if usbguard is not installed #567
datetime:
- Optimizations of the required DB lookups
==============
Version 3.38.1
==============
......
project(
'gnome-settings-daemon', 'c',
version: '3.38.1',
version: '3.38.2',
license: [ 'GPL2+', 'LGPLv2+' ],
meson_version: '>= 0.47.0'
)
......
......@@ -49,8 +49,6 @@ typedef struct
GClueSimple *geoclue_simple;
GCancellable *geoclue_cancellable;
TzDB *tzdb;
WeatherTzDB *weather_tzdb;
gchar *current_timezone;
GSettings *location_settings;
......@@ -171,23 +169,28 @@ find_by_country (GList *locations,
return found;
}
static const gchar *
static gchar *
find_timezone (GsdTimezoneMonitor *self,
GeocodeLocation *location,
const gchar *country_code)
{
TzDB *tzdb;
gchar *res;
GList *filtered;
GList *weather_locations;
GList *locations;
GsdTimezoneMonitorPrivate *priv = gsd_timezone_monitor_get_instance_private (self);
TzLocation *closest_tz_location;
tzdb = tz_load_db ();
/* First load locations from Olson DB */
locations = ptr_array_to_list (tz_get_locations (priv->tzdb));
locations = ptr_array_to_list (tz_get_locations (tzdb));
g_return_val_if_fail (locations != NULL, NULL);
/* ... and then add libgweather's locations as well */
weather_locations = weather_tz_db_get_locations (country_code);
locations = g_list_concat (locations,
weather_tz_db_get_locations (priv->weather_tzdb));
g_list_copy (weather_locations));
/* Filter tz locations by country */
filtered = find_by_country (locations, country_code);
......@@ -202,9 +205,13 @@ find_timezone (GsdTimezoneMonitor *self,
locations = sort_by_closest_to (locations, location);
closest_tz_location = (TzLocation *) locations->data;
res = g_strdup (closest_tz_location->zone);
g_list_free (locations);
g_list_free_full (weather_locations, (GDestroyNotify) tz_location_free);
tz_db_free (tzdb);
return closest_tz_location->zone;
return res;
}
static void
......@@ -214,7 +221,7 @@ process_location (GsdTimezoneMonitor *self,
GeocodeLocation *location;
GsdTimezoneMonitorPrivate *priv = gsd_timezone_monitor_get_instance_private (self);
const gchar *country_code;
const gchar *new_timezone;
g_autofree gchar *new_timezone = NULL;
country_code = geocode_place_get_country_code (place);
location = geocode_place_get_location (place);
......@@ -386,8 +393,6 @@ gsd_timezone_monitor_finalize (GObject *obj)
g_clear_object (&priv->dtm);
g_clear_object (&priv->permission);
g_clear_pointer (&priv->current_timezone, g_free);
g_clear_pointer (&priv->tzdb, tz_db_free);
g_clear_pointer (&priv->weather_tzdb, weather_tz_db_free);
g_clear_object (&priv->location_settings);
......@@ -459,8 +464,6 @@ gsd_timezone_monitor_init (GsdTimezoneMonitor *self)
}
priv->current_timezone = timedate1_dup_timezone (priv->dtm);
priv->tzdb = tz_load_db ();
priv->weather_tzdb = weather_tz_db_new ();
priv->location_settings = g_settings_new ("org.gnome.system.location");
g_signal_connect_swapped (priv->location_settings, "changed::enabled",
......
......@@ -25,11 +25,6 @@
#define GWEATHER_I_KNOW_THIS_IS_UNSTABLE
#include <libgweather/gweather.h>
struct _WeatherTzDB
{
GList *tz_locations;
};
static GList *
location_get_cities (GWeatherLocation *parent_location)
{
......@@ -104,33 +99,24 @@ load_timezones (GList *cities)
}
GList *
weather_tz_db_get_locations (WeatherTzDB *tzdb)
{
return g_list_copy (tzdb->tz_locations);
}
WeatherTzDB *
weather_tz_db_new (void)
weather_tz_db_get_locations (const gchar *country_code)
{
GList *cities;
GList *tz_locations;
GWeatherLocation *world;
WeatherTzDB *tzdb;
GWeatherLocation *country;
world = gweather_location_get_world ();
cities = location_get_cities (world);
tzdb = g_new0 (WeatherTzDB, 1);
tzdb->tz_locations = load_timezones (cities);
country = gweather_location_find_by_country_code (world, country_code);
g_list_free (cities);
if (!country)
return NULL;
return tzdb;
}
cities = location_get_cities (country);
tz_locations = load_timezones (cities);
void
weather_tz_db_free (WeatherTzDB *tzdb)
{
g_list_free_full (tzdb->tz_locations, (GDestroyNotify) tz_location_free);
g_list_free (cities);
g_free (tzdb);
return tz_locations;
}
......@@ -22,10 +22,6 @@
#include <glib.h>
typedef struct _WeatherTzDB WeatherTzDB;
WeatherTzDB *weather_tz_db_new (void);
GList *weather_tz_db_get_locations (WeatherTzDB *db);
void weather_tz_db_free (WeatherTzDB *db);
GList *weather_tz_db_get_locations (const char *country);
#endif /* __WEATHER_TZ_H */
......@@ -78,7 +78,7 @@ typedef struct {
typedef struct {
gint64 atime;
gint64 time;
char *path;
glong size;
} ThumbData;
......@@ -100,11 +100,13 @@ read_dir_for_purge (const char *path, GList *files)
{
GFile *read_path;
GFileEnumerator *enum_dir;
int cannot_get_time = 0;
read_path = g_file_new_for_path (path);
enum_dir = g_file_enumerate_children (read_path,
G_FILE_ATTRIBUTE_STANDARD_NAME ","
G_FILE_ATTRIBUTE_TIME_ACCESS ","
G_FILE_ATTRIBUTE_TIME_MODIFIED ","
G_FILE_ATTRIBUTE_STANDARD_SIZE,
G_FILE_QUERY_INFO_NONE,
NULL,
......@@ -120,28 +122,31 @@ read_dir_for_purge (const char *path, GList *files)
ThumbData *td;
GFile *entry;
char *entry_path;
gint64 atime;
gint64 time;
entry = g_file_get_child (read_path, name);
entry_path = g_file_get_path (entry);
g_object_unref (entry);
// Note that using atime here is no worse than using mtime.
// If atime is available, it should be no worse than mtime.
// - Even if the file system is mounted with noatime, the atime and
// mtime will be set to the same value on file creation.
// - Since the thumbnailer never edits thumbnails, and instead swaps
// in newly created temp files, atime will always be >= mtime.
// - atime should never be absent, which would cause
// g_file_info_get_attribute_int64 to return 0. The presence of
// atime is determined by the filters we pass to
// g_file_enumerate_children, not the file system atime settings.
g_assert (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_TIME_ACCESS));
atime = g_file_info_get_attribute_uint64 (info, G_FILE_ATTRIBUTE_TIME_ACCESS);
if (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_TIME_ACCESS)) {
time = g_file_info_get_attribute_uint64 (info, G_FILE_ATTRIBUTE_TIME_ACCESS);
} else if (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_TIME_MODIFIED)) {
time = g_file_info_get_attribute_uint64 (info, G_FILE_ATTRIBUTE_TIME_MODIFIED);
} else {
// Unlikely to get here, but be defensive
cannot_get_time += 1;
time = G_MAXINT64;
}
td = g_new0 (ThumbData, 1);
td->path = entry_path;
td->atime = atime;
td->time = time;
td->size = g_file_info_get_size (info);
files = g_list_prepend (files, td);
......@@ -149,6 +154,10 @@ read_dir_for_purge (const char *path, GList *files)
g_object_unref (info);
}
g_object_unref (enum_dir);
if (cannot_get_time > 0) {
g_warning ("Could not read atime or mtime on %d files in %s", cannot_get_time, path);
}
}
g_object_unref (read_path);
......@@ -158,7 +167,7 @@ read_dir_for_purge (const char *path, GList *files)
static void
purge_old_thumbnails (ThumbData *info, PurgeData *purge_data)
{
if ((purge_data->now - info->atime) > purge_data->max_age) {
if ((purge_data->now - info->time) > purge_data->max_age) {
g_unlink (info->path);
info->size = 0;
} else {
......@@ -167,9 +176,9 @@ purge_old_thumbnails (ThumbData *info, PurgeData *purge_data)
}
static int
sort_file_atime (ThumbData *file1, ThumbData *file2)
sort_file_time (ThumbData *file1, ThumbData *file2)
{
return file1->atime - file2->atime;
return file1->time - file2->time;
}
static char **
......@@ -260,7 +269,7 @@ purge_thumbnail_cache (GsdHousekeepingManager *manager)
if ((purge_data.total_size > purge_data.max_size) && (purge_data.max_size >= 0)) {
GList *scan;
files = g_list_sort (files, (GCompareFunc) sort_file_atime);
files = g_list_sort (files, (GCompareFunc) sort_file_time);
for (scan = files; scan && (purge_data.total_size > purge_data.max_size); scan = scan->next) {
ThumbData *info = scan->data;
g_unlink (info->path);
......
......@@ -161,6 +161,7 @@ struct _GsdPowerManager
NotifyNotification *notification_low;
NotifyNotification *notification_sleep_warning;
GsdPowerActionType sleep_action_type;
GHashTable *devices_notified_ht; /* key = serial str, value = UpDeviceLevel */
gboolean battery_is_low; /* laptop battery low, or UPS discharging */
/* Brightness */
......@@ -449,6 +450,39 @@ manager_critical_action_stop_sound_cb (GsdPowerManager *manager)
return FALSE;
}
static gboolean
engine_device_debounce_warn (GsdPowerManager *manager,
UpDeviceKind kind,
UpDeviceLevel warning,
const char *serial)
{
gpointer last_warning_ptr;
UpDeviceLevel last_warning;
gboolean ret = TRUE;
if (!serial)
return TRUE;
if (kind == UP_DEVICE_KIND_BATTERY ||
kind == UP_DEVICE_KIND_UPS)
return TRUE;
if (g_hash_table_lookup_extended (manager->devices_notified_ht, serial,
NULL, &last_warning_ptr)) {
last_warning = GPOINTER_TO_INT (last_warning_ptr);
if (last_warning >= warning)
ret = FALSE;
}
if (warning != UP_DEVICE_LEVEL_UNKNOWN)
g_hash_table_insert (manager->devices_notified_ht,
g_strdup (serial),
GINT_TO_POINTER (warning));
return ret;
}
static void
engine_charge_low (GsdPowerManager *manager, UpDevice *device)
{
......@@ -894,14 +928,19 @@ engine_charge_action (GsdPowerManager *manager, UpDevice *device)
static void
engine_device_warning_changed_cb (UpDevice *device, GParamSpec *pspec, GsdPowerManager *manager)
{
g_autofree char *serial = NULL;
UpDeviceLevel warning;
UpDeviceKind kind;
g_object_get (device,
"serial", &serial,
"warning-level", &warning,
"kind", &kind,
NULL);
if (!engine_device_debounce_warn (manager, kind, warning, serial))
return;
if (warning == UP_DEVICE_LEVEL_DISCHARGING) {
g_debug ("** EMIT: discharging");
engine_ups_discharging (manager, device);
......@@ -985,6 +1024,11 @@ static void
gnome_session_logout (GsdPowerManager *manager,
guint logout_mode)
{
if (g_getenv ("RUNNING_UNDER_GDM")) {
g_warning ("Prevented logout from GDM session! This indicates an issue in gsd-power.");
return;
}
g_dbus_proxy_call (G_DBUS_PROXY (manager->session),
"Logout",
g_variant_new ("(u)", logout_mode),
......@@ -1805,6 +1849,13 @@ idle_configure (GsdPowerManager *manager)
timeout_sleep = 0;
}
/* don't do any automatic logout if we are in GDM */
if (g_getenv ("RUNNING_UNDER_GDM") &&
(action_type == GSD_POWER_ACTION_LOGOUT)) {
g_debug ("Ignoring sleep timeout with logout action inside GDM");
timeout_sleep = 0;
}
if (timeout_sleep != 0) {
g_debug ("setting up sleep callback %is", timeout_sleep);
......@@ -2559,6 +2610,8 @@ on_rr_screen_acquired (GObject *object,
manager);
manager->devices_array = g_ptr_array_new_with_free_func (g_object_unref);
manager->devices_notified_ht = g_hash_table_new_full (g_str_hash, g_str_equal,
g_free, NULL);
/* create a fake virtual composite battery */
manager->device_composite = up_client_get_display_device (manager->up_client);
......@@ -2803,6 +2856,7 @@ gsd_power_manager_stop (GsdPowerManager *manager)
g_clear_pointer (&manager->devices_array, g_ptr_array_unref);
g_clear_object (&manager->device_composite);
g_clear_pointer (&manager->devices_notified_ht, g_hash_table_destroy);
g_clear_object (&manager->screensaver_proxy);
......
......@@ -942,6 +942,101 @@ class PowerPluginTest6(PowerPluginBase):
# verify notification
self.assertRegex(notify_log, b'[0-9.]+ Notify "Power" .* ".*" ".*Wireless mouse .*low.* power.*\([0-9.]+%\).*"')
def test_notify_device_spam(self):
'''no repeat notifications for device batteries'''
# Set internal battery to discharging
self.set_composite_battery_discharging()
# Add a device battery
bat2_path = '/org/freedesktop/UPower/devices/' + 'mock_MOUSE_BAT1'
self.obj_upower.AddObject(bat2_path,
'org.freedesktop.UPower.Device',
{
'PowerSupply': dbus.Boolean(False, variant_level=1),
'IsPresent': dbus.Boolean(True, variant_level=1),
'Model': dbus.String('Bat1', variant_level=1),
'Serial': dbus.String('12345678', variant_level=1),
'Percentage': dbus.Double(10.0, variant_level=1),
'State': dbus.UInt32(UPowerGlib.DeviceState.DISCHARGING, variant_level=1),
'Type': dbus.UInt32(UPowerGlib.DeviceKind.MOUSE, variant_level=1),
'WarningLevel': dbus.UInt32(UPowerGlib.DeviceLevel.LOW, variant_level=1),
}, dbus.Array([], signature='(ssss)'))
obj_bat2 = self.system_bus_con.get_object('org.freedesktop.UPower', bat2_path)
self.obj_upower.EmitSignal('', 'DeviceAdded', 'o', [bat2_path],
dbus_interface='org.freedesktop.DBus.Mock')
time.sleep(1)
self.check_plugin_log('EMIT: charge-low', 2)
time.sleep(0.5)
# we should have gotten a notification by now
notify_log = self.p_notify.stdout.read()
# verify notification
self.assertRegex(notify_log, b'[0-9.]+ Notify "Power" .* ".*" ".*Wireless mouse .*low.* power.*\([0-9.]+%\).*"')
# Disconnect mouse
self.obj_upower.RemoveObject(bat2_path)
time.sleep(0.5)
# Reconnect mouse
self.obj_upower.AddObject(bat2_path,
'org.freedesktop.UPower.Device',
{
'PowerSupply': dbus.Boolean(False, variant_level=1),
'IsPresent': dbus.Boolean(True, variant_level=1),
'Model': dbus.String('Bat1', variant_level=1),
'Serial': dbus.String('12345678', variant_level=1),
'Percentage': dbus.Double(10.0, variant_level=1),
'State': dbus.UInt32(UPowerGlib.DeviceState.DISCHARGING, variant_level=1),
'Type': dbus.UInt32(UPowerGlib.DeviceKind.MOUSE, variant_level=1),
'WarningLevel': dbus.UInt32(UPowerGlib.DeviceLevel.LOW, variant_level=1),
}, dbus.Array([], signature='(ssss)'))
obj_bat2 = self.system_bus_con.get_object('org.freedesktop.UPower', bat2_path)
self.obj_upower.EmitSignal('', 'DeviceAdded', 'o', [bat2_path],
dbus_interface='org.freedesktop.DBus.Mock')
time.sleep(1)
# we shouldn't have gotten a notification by now
notify_log = self.p_notify.stdout.read()
self.assertIsNone(notify_log)
# Disconnect mouse
self.obj_upower.RemoveObject(bat2_path)
time.sleep(0.5)
# Reconnect mouse with critical battery level
self.obj_upower.AddObject(bat2_path,
'org.freedesktop.UPower.Device',
{
'PowerSupply': dbus.Boolean(False, variant_level=1),
'IsPresent': dbus.Boolean(True, variant_level=1),
'Model': dbus.String('Bat1', variant_level=1),
'Serial': dbus.String('12345678', variant_level=1),
'Percentage': dbus.Double(5.0, variant_level=1),
'State': dbus.UInt32(UPowerGlib.DeviceState.DISCHARGING, variant_level=1),
'Type': dbus.UInt32(UPowerGlib.DeviceKind.MOUSE, variant_level=1),
'WarningLevel': dbus.UInt32(UPowerGlib.DeviceLevel.CRITICAL, variant_level=1),
}, dbus.Array([], signature='(ssss)'))
obj_bat2 = self.system_bus_con.get_object('org.freedesktop.UPower', bat2_path)
self.obj_upower.EmitSignal('', 'DeviceAdded', 'o', [bat2_path],
dbus_interface='org.freedesktop.DBus.Mock')
time.sleep(1)
# Verify new warning
self.check_plugin_log('EMIT: charge-critical', 2)
time.sleep(0.5)
# we should have gotten a notification by now
notify_log = self.p_notify.stdout.read()
# verify notification
self.assertRegex(notify_log, b'[0-9.]+ Notify "Power" .* ".*" ".*Wireless mouse .*very low.* power.*\([0-9.]+%\).*"')
def test_notify_device_battery_coarse_level(self):
'''critical power level notification for device batteries with coarse level'''
......
......@@ -445,6 +445,7 @@ _cc_rfkill_glib_open (CcRfkillGlib *rfkill,
/* Setup monitoring */
rfkill->channel = g_io_channel_unix_new (fd);
g_io_channel_set_encoding (rfkill->channel, NULL, NULL);
g_io_channel_set_buffered (rfkill->channel, FALSE);
rfkill->watch_id = g_io_add_watch (rfkill->channel,
G_IO_IN | G_IO_HUP | G_IO_ERR,
(GIOFunc) event_cb,
......
......@@ -154,7 +154,8 @@ dbus_call_log_error (GObject *source_object,
result = g_dbus_proxy_call_finish (G_DBUS_PROXY (source_object),
res,
&error);
if (result == NULL)
if (result == NULL &&
!g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_SERVICE_UNKNOWN))
g_warning ("%s: %s", msg, error->message);
}
......
This diff is collapsed.
......@@ -30,9 +30,9 @@
msgid ""
msgstr ""
"Project-Id-Version: gnome-settings-daemon master\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-settings-daemon/iss"
"ues\n"
"POT-Creation-Date: 2020-09-03 20:47+0000\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-settings-daemon/"
"issues\n"
"POT-Creation-Date: 2020-10-28 13:36+0000\n"
"PO-Revision-Date: 2020-09-05 22:06+0200\n"
"Last-Translator: Mario Blättermann <mario.blaettermann@gmail.com>\n"
"Language-Team: Deutsch <gnome-de@gnome.org>\n"
......@@ -1450,7 +1450,7 @@ msgid ""
"before it goes to sleep. A value of 0 means never."
msgstr ""
"Zeit in Sekunden, die der Rechner bei Netzanschluss inaktiv sein muss, bevor "
"er in den Energiesparmodus versetzt wird. Ein Wert von O bedeutet nie."
"er in den Energiesparmodus versetzt wird. Ein Wert von 0 bedeutet nie."
#: data/org.gnome.settings-daemon.plugins.power.gschema.xml.in:21
#: data/org.gnome.settings-daemon.plugins.power.gschema.xml.in:31
......@@ -1475,7 +1475,7 @@ msgid ""
"inactive before it goes to sleep. A value of 0 means never."
msgstr ""
"Zeit in Sekunden, die der Rechner im Akkubetrieb inaktiv sein muss, bevor er "
"in den Energiesparmodus versetzt wird. Ein Wert von O bedeutet nie."
"in den Energiesparmodus versetzt wird. Ein Wert von 0 bedeutet nie."
#: data/org.gnome.settings-daemon.plugins.power.gschema.xml.in:36
msgid "Enable the ALS sensor"
......@@ -1725,30 +1725,30 @@ msgstr ""
msgid "This computer has only %s disk space remaining."
msgstr "Auf diesem Rechner ist nur noch %s Speicherplatz verfügbar."
#: plugins/media-keys/gsd-media-keys-manager.c:2468
#: plugins/media-keys/gsd-media-keys-manager.c:2476
msgid "Bluetooth disabled"
msgstr "Bluetooth ist deaktiviert"
#: plugins/media-keys/gsd-media-keys-manager.c:2471
#: plugins/media-keys/gsd-media-keys-manager.c:2479
msgid "Bluetooth enabled"
msgstr "Bluetooth ist aktiviert"
#: plugins/media-keys/gsd-media-keys-manager.c:2475
#: plugins/media-keys/gsd-media-keys-manager.c:2483
msgid "Airplane mode enabled"
msgstr "Flugzeugmodus ist aktiviert"
#: plugins/media-keys/gsd-media-keys-manager.c:2478
#: plugins/media-keys/gsd-media-keys-manager.c:2486
msgid "Airplane mode disabled"
msgstr "Flugzeugmodus ist deaktiviert"
#: plugins/media-keys/gsd-media-keys-manager.c:2507
#: plugins/media-keys/gsd-media-keys-manager.c:2515
msgid "Hardware Airplane Mode"
msgstr "Hardware-Flugzeugmodus"
#. Translators: this is a filename used for screencast
#. * recording, where "%d" and "%t" date and time, e.g.
#. * "Screencast from 07-17-2013 10:00:46 PM.webm"
#: plugins/media-keys/gsd-media-keys-manager.c:2570
#: plugins/media-keys/gsd-media-keys-manager.c:2578
#, no-c-format
msgid "Screencast from %d %t.webm"
msgstr "Bildschirmvideo von %d %t.webm"
......@@ -2178,46 +2178,46 @@ msgstr ""
"Rechner wird deshalb nun heruntergefahren."
#. TRANSLATORS: this is the sound description
#: plugins/power/gsd-power-manager.c:1333
#: plugins/power/gsd-power-manager.c:1338
msgid "Lid has been opened"
msgstr "Klappe wurde geöffnet"
#. TRANSLATORS: this is the sound description
#: plugins/power/gsd-power-manager.c:1367
#: plugins/power/gsd-power-manager.c:1372
msgid "Lid has been closed"
msgstr "Klappe wurde geschlossen"
#. TRANSLATORS: this is the sound description
#: plugins/power/gsd-power-manager.c:1934
#: plugins/power/gsd-power-manager.c:1946
msgid "On battery power"
msgstr "Batteriebetrieb"
#. TRANSLATORS: this is the sound description
#: plugins/power/gsd-power-manager.c:1939
#: plugins/power/gsd-power-manager.c:1951
msgid "On AC power"
msgstr "Netzbetrieb"
#: plugins/power/gsd-power-manager.c:2127
#: plugins/power/gsd-power-manager.c:2139