[gnome-disk-utility] Be a bit more careful when checking power state



commit 8138f4378e90a4a4d168a59c53e51231f1d2b89e
Author: David Zeuthen <zeuthen gmail com>
Date:   Fri Jul 27 12:17:06 2012 -0400

    Be a bit more careful when checking power state
    
    In particular, don't submit a request if one is still pending. Also,
    stop checking if a request failed.
    
    Signed-off-by: David Zeuthen <zeuthen gmail com>

 src/disks/gdudevicetreemodel.c |  112 +++++++++++++++++++++++++++++-----------
 src/disks/gdudevicetreemodel.h |    2 +-
 src/disks/gduenums.h           |   15 +++++
 src/disks/gdutypes.h           |    7 ---
 src/disks/gduwindow.c          |   38 +++++++++++---
 5 files changed, 128 insertions(+), 46 deletions(-)
---
diff --git a/src/disks/gdudevicetreemodel.c b/src/disks/gdudevicetreemodel.c
index 824c328..9a140f1 100644
--- a/src/disks/gdudevicetreemodel.c
+++ b/src/disks/gdudevicetreemodel.c
@@ -27,6 +27,7 @@
 
 #include "gdudevicetreemodel.h"
 #include "gduatasmartdialog.h"
+#include "gduenumtypes.h"
 #include "gduutils.h"
 
 struct _GduDeviceTreeModel
@@ -312,28 +313,41 @@ pm_get_state_cb (GObject       *source_object,
 {
   GduDeviceTreeModel *model = GDU_DEVICE_TREE_MODEL (user_data);
   GDBusObject *object;
-  gboolean sleeping;
+  GduPowerStateFlags flags;
   guchar state;
   GError *error = NULL;
 
+  flags = GDU_POWER_STATE_FLAGS_NONE;
+
   if (!udisks_drive_ata_call_pm_get_state_finish (UDISKS_DRIVE_ATA (source_object),
                                                   &state,
                                                   res,
                                                   &error))
     {
-      if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+      if (g_error_matches (error, UDISKS_ERROR, UDISKS_ERROR_DEVICE_BUSY))
+        {
+          /* this means that a secure erase in progress.. so no error-spew and try again */
+        }
+      else
         {
-          g_printerr ("Error calling Drive.Ata.PmGetState: %s (%s, %d)\n",
-                      error->message, g_quark_to_string (error->domain), error->code);
+          if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+            {
+              g_printerr ("Error calling Drive.Ata.PmGetState: %s (%s, %d)\n",
+                          error->message, g_quark_to_string (error->domain), error->code);
+              /* set a flag so we won't try again */
+              flags |= GDU_POWER_STATE_FLAGS_FAILED;
+            }
         }
       g_clear_error (&error);
       goto out;
     }
 
-  sleeping = TRUE;
-  if (state == 0x80 || state == 0xff)
-    sleeping = FALSE;
+  if (!(state == 0x80 || state == 0xff))
+    {
+      flags |= GDU_POWER_STATE_FLAGS_STANDBY;
+    }
 
+ out:
   object = g_dbus_interface_get_object (G_DBUS_INTERFACE (source_object));
   if (object != NULL)
     {
@@ -342,42 +356,80 @@ pm_get_state_cb (GObject       *source_object,
         {
           gtk_tree_store_set (GTK_TREE_STORE (model),
                               &iter,
-                              GDU_DEVICE_TREE_MODEL_COLUMN_SLEEPING, sleeping,
+                              GDU_DEVICE_TREE_MODEL_COLUMN_POWER_STATE_FLAGS, flags,
                               -1);
         }
     }
 
- out:
   g_object_unref (model);
 }
 
+
 static gboolean
-on_pefs_timeout (gpointer user_data)
+pefs_timeout_foreach_cb (GtkTreeModel  *_model,
+                         GtkTreePath   *path,
+                         GtkTreeIter   *iter,
+                         gpointer       user_data)
 {
-  GduDeviceTreeModel *model = GDU_DEVICE_TREE_MODEL (user_data);
-  GList *l;
+  GduDeviceTreeModel *model = GDU_DEVICE_TREE_MODEL (_model);
+  UDisksObject *object = NULL;
+  UDisksDriveAta *ata = NULL;
+  GduPowerStateFlags cur_flags = GDU_POWER_STATE_FLAGS_NONE;
 
-  for (l = model->current_drives; l != NULL; l = l->next)
+  gtk_tree_model_get (GTK_TREE_MODEL (model),
+                      iter,
+                      GDU_DEVICE_TREE_MODEL_COLUMN_OBJECT, &object,
+                      GDU_DEVICE_TREE_MODEL_COLUMN_POWER_STATE_FLAGS, &cur_flags,
+                      -1);
+
+  if (object == NULL)
+    goto out;
+
+  /* Don't check power state if
+   *
+   *  - a check is already pending; or
+   *  - a check failed in the past
+   */
+  if (cur_flags & GDU_POWER_STATE_FLAGS_CHECKING || cur_flags & GDU_POWER_STATE_FLAGS_FAILED)
     {
-      UDisksObject *object = UDISKS_OBJECT (l->data);
-      UDisksDriveAta *ata;
+      g_print ("nah cur_flags=%d\n", cur_flags);
+      goto out;
+    }
 
-      ata = udisks_object_peek_drive_ata (object);
-      if (ata != NULL &&
-          udisks_drive_ata_get_pm_supported (ata) &&
-          udisks_drive_ata_get_pm_enabled (ata))
-        {
-          GVariantBuilder options_builder;
-          g_variant_builder_init (&options_builder, G_VARIANT_TYPE_VARDICT);
-          g_variant_builder_add (&options_builder, "{sv}", "auth.no_user_interaction", g_variant_new_boolean (TRUE));
-          udisks_drive_ata_call_pm_get_state (ata,
-                                              g_variant_builder_end (&options_builder),
-                                              NULL, /* GCancellable */
-                                              pm_get_state_cb,
-                                              g_object_ref (model));
-        }
+  ata = udisks_object_peek_drive_ata (object);
+  if (ata != NULL && udisks_drive_ata_get_pm_supported (ata) && udisks_drive_ata_get_pm_enabled (ata))
+    {
+      GVariantBuilder options_builder;
+      g_variant_builder_init (&options_builder, G_VARIANT_TYPE_VARDICT);
+      g_variant_builder_add (&options_builder,
+                             "{sv}", "auth.no_user_interaction", g_variant_new_boolean (TRUE));
+      udisks_drive_ata_call_pm_get_state (ata,
+                                          g_variant_builder_end (&options_builder),
+                                          NULL, /* GCancellable */
+                                          pm_get_state_cb,
+                                          g_object_ref (model));
+
+      cur_flags |= GDU_POWER_STATE_FLAGS_CHECKING;
+      gtk_tree_store_set (GTK_TREE_STORE (model),
+                          iter,
+                          GDU_DEVICE_TREE_MODEL_COLUMN_POWER_STATE_FLAGS, cur_flags,
+                          -1);
     }
 
+  /* TODO: add support for other PM interfaces */
+
+ out:
+  g_clear_object (&object);
+  return FALSE; /* continue iterating */
+}
+
+static gboolean
+on_pefs_timeout (gpointer user_data)
+{
+  GduDeviceTreeModel *model = GDU_DEVICE_TREE_MODEL (user_data);
+  gtk_tree_model_foreach (GTK_TREE_MODEL (model),
+                          pefs_timeout_foreach_cb,
+                          NULL);
   return TRUE; /* keep timeout around */
 }
 
@@ -400,7 +452,7 @@ gdu_device_tree_model_constructed (GObject *object)
   types[6] = G_TYPE_BOOLEAN;
   types[7] = G_TYPE_UINT;
   types[8] = G_TYPE_BOOLEAN;
-  types[9] = G_TYPE_BOOLEAN;
+  types[9] = GDU_TYPE_POWER_STATE_FLAGS;
   gtk_tree_store_set_column_types (GTK_TREE_STORE (model),
                                    GDU_DEVICE_TREE_MODEL_N_COLUMNS,
                                    types);
diff --git a/src/disks/gdudevicetreemodel.h b/src/disks/gdudevicetreemodel.h
index de100b8..7afc919 100644
--- a/src/disks/gdudevicetreemodel.h
+++ b/src/disks/gdudevicetreemodel.h
@@ -43,7 +43,7 @@ enum
   GDU_DEVICE_TREE_MODEL_COLUMN_WARNING,
   GDU_DEVICE_TREE_MODEL_COLUMN_PULSE,
   GDU_DEVICE_TREE_MODEL_COLUMN_JOBS_RUNNING,
-  GDU_DEVICE_TREE_MODEL_COLUMN_SLEEPING,
+  GDU_DEVICE_TREE_MODEL_COLUMN_POWER_STATE_FLAGS,
   GDU_DEVICE_TREE_MODEL_N_COLUMNS
 };
 
diff --git a/src/disks/gduenums.h b/src/disks/gduenums.h
index 0ea71ad..ef3201f 100644
--- a/src/disks/gduenums.h
+++ b/src/disks/gduenums.h
@@ -35,6 +35,21 @@ typedef enum
   GDU_VOLUME_GRID_ELEMENT_TYPE_DEVICE
 } GduVolumeGridElementType;
 
+typedef enum
+{
+  GDU_FORMAT_DURATION_FLAGS_NONE                 = 0,
+  GDU_FORMAT_DURATION_FLAGS_SUBSECOND_PRECISION  = (1<<0),
+  GDU_FORMAT_DURATION_FLAGS_NO_SECONDS           = (1<<1)
+} GduFormatDurationFlags;
+
+typedef enum
+{
+  GDU_POWER_STATE_FLAGS_NONE              = 0,
+  GDU_POWER_STATE_FLAGS_STANDBY           = (1<<0),
+  GDU_POWER_STATE_FLAGS_CHECKING          = (1<<1),
+  GDU_POWER_STATE_FLAGS_FAILED            = (1<<2)
+} GduPowerStateFlags;
+
 G_END_DECLS
 
 #endif /* __GDU_ENUMS_H__ */
diff --git a/src/disks/gdutypes.h b/src/disks/gdutypes.h
index 005d73e..917908a 100644
--- a/src/disks/gdutypes.h
+++ b/src/disks/gdutypes.h
@@ -52,13 +52,6 @@ typedef struct _GduPasswordStrengthWidget GduPasswordStrengthWidget;
 struct _GduEstimator;
 typedef struct _GduEstimator GduEstimator;
 
-typedef enum
-{
-  GDU_FORMAT_DURATION_FLAGS_NONE                 = 0,
-  GDU_FORMAT_DURATION_FLAGS_SUBSECOND_PRECISION  = (1<<0),
-  GDU_FORMAT_DURATION_FLAGS_NO_SECONDS           = (1<<1)
-} GduFormatDurationFlags;
-
 G_END_DECLS
 
 #endif /* __GDU_TYPES_H__ */
diff --git a/src/disks/gduwindow.c b/src/disks/gduwindow.c
index de28d49..aa03257 100644
--- a/src/disks/gduwindow.c
+++ b/src/disks/gduwindow.c
@@ -959,6 +959,26 @@ device_sort_function (GtkTreeModel *model,
   return g_strcmp0 (sa, sb);
 }
 
+static void
+power_state_cell_func (GtkTreeViewColumn *column,
+                       GtkCellRenderer   *renderer,
+                       GtkTreeModel      *model,
+                       GtkTreeIter       *iter,
+                       gpointer           user_data)
+{
+  gboolean visible = FALSE;
+  GduPowerStateFlags flags;
+
+  gtk_tree_model_get (model,
+                      iter,
+                      GDU_DEVICE_TREE_MODEL_COLUMN_POWER_STATE_FLAGS, &flags,
+                      -1);
+
+  if (flags & GDU_POWER_STATE_FLAGS_STANDBY)
+    visible = TRUE;
+
+  gtk_cell_renderer_set_visible (renderer, visible);
+}
 
 static void
 gdu_window_constructed (GObject *object)
@@ -1089,10 +1109,12 @@ gdu_window_constructed (GObject *object)
                 "icon-name", "gnome-disks-state-standby-symbolic",
                 NULL);
   gtk_tree_view_column_pack_end (column, renderer, FALSE);
-  gtk_tree_view_column_set_attributes (column,
-                                       renderer,
-                                       "visible", GDU_DEVICE_TREE_MODEL_COLUMN_SLEEPING,
-                                       NULL);
+
+  gtk_tree_view_column_set_cell_data_func (column,
+                                           renderer,
+                                           power_state_cell_func,
+                                           NULL,  /* user_data */
+                                           NULL); /* user_data GDestroyNotify */
 
   /* expand on insertion - hmm, I wonder if there's an easier way to do this */
   g_signal_connect (window->model,
@@ -1917,14 +1939,14 @@ update_device_page_for_drive (GduWindow      *window,
       if (udisks_drive_ata_get_pm_supported (ata) && !is_ssd)
         {
           GtkTreeIter iter;
-          gboolean sleeping = FALSE;
+          GduPowerStateFlags power_state_flags = GDU_POWER_STATE_FLAGS_NONE;
           if (gdu_device_tree_model_get_iter_for_object (window->model, object, &iter))
             {
               gtk_tree_model_get (GTK_TREE_MODEL (window->model), &iter,
-                                  GDU_DEVICE_TREE_MODEL_COLUMN_SLEEPING,
-                                  &sleeping, -1);
+                                  GDU_DEVICE_TREE_MODEL_COLUMN_POWER_STATE_FLAGS, &power_state_flags,
+                                  -1);
             }
-          if (sleeping)
+          if (power_state_flags & GDU_POWER_STATE_FLAGS_STANDBY)
             *show_flags |= SHOW_FLAGS_DISK_POPUP_MENU_RESUME_NOW;
           else
             *show_flags |= SHOW_FLAGS_DISK_POPUP_MENU_STANDBY_NOW;



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]