Back to index

indicator-power  12.10.0
device.c
Go to the documentation of this file.
00001 /*
00002 
00003 A simple Device structure used internally by indicator-power
00004 
00005 Copyright 2012 Canonical Ltd.
00006 
00007 Authors:
00008     Charles Kerr <charles.kerr@canonical.com>
00009 
00010 This library is free software; you can redistribute it and/or
00011 modify it under the terms of the GNU General Public License
00012 version 3.0 as published by the Free Software Foundation.
00013 
00014 This library is distributed in the hope that it will be useful,
00015 but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017 GNU General Public License version 3.0 for more details.
00018 
00019 You should have received a copy of the GNU General Public
00020 License along with this library. If not, see
00021 <http://www.gnu.org/licenses/>.
00022 */
00023 
00024 #ifdef HAVE_CONFIG_H
00025  #include "config.h"
00026 #endif
00027 
00028 #include <glib/gi18n.h>
00029 
00030 #include "device.h"
00031 
00032 struct _IndicatorPowerDevicePrivate
00033 {
00034   UpDeviceKind kind;
00035   UpDeviceState state;
00036   gchar * object_path;
00037   gdouble percentage;
00038   time_t time;
00039 };
00040 
00041 #define INDICATOR_POWER_DEVICE_GET_PRIVATE(o) (INDICATOR_POWER_DEVICE(o)->priv)
00042 
00043 /* Properties */
00044 /* Enum for the properties so that they can be quickly found and looked up. */
00045 enum {
00046   PROP_0,
00047   PROP_KIND,
00048   PROP_STATE,
00049   PROP_OBJECT_PATH,
00050   PROP_PERCENTAGE,
00051   PROP_TIME,
00052   N_PROPERTIES
00053 };
00054 
00055 static GParamSpec * properties[N_PROPERTIES];
00056 
00057 /* GObject stuff */
00058 static void indicator_power_device_class_init (IndicatorPowerDeviceClass *klass);
00059 static void indicator_power_device_init       (IndicatorPowerDevice *self);
00060 static void indicator_power_device_dispose    (GObject *object);
00061 static void indicator_power_device_finalize   (GObject *object);
00062 static void set_property (GObject*, guint prop_id, const GValue*, GParamSpec* );
00063 static void get_property (GObject*, guint prop_id,       GValue*, GParamSpec* );
00064 
00065 /* LCOV_EXCL_START */
00066 G_DEFINE_TYPE (IndicatorPowerDevice, indicator_power_device, G_TYPE_OBJECT);
00067 /* LCOV_EXCL_STOP */
00068 
00069 static void
00070 indicator_power_device_class_init (IndicatorPowerDeviceClass *klass)
00071 {
00072   GObjectClass *object_class = G_OBJECT_CLASS (klass);
00073 
00074   g_type_class_add_private (klass, sizeof (IndicatorPowerDevicePrivate));
00075 
00076   object_class->dispose = indicator_power_device_dispose;
00077   object_class->finalize = indicator_power_device_finalize;
00078   object_class->set_property = set_property;
00079   object_class->get_property = get_property;
00080 
00081   properties[PROP_KIND] = g_param_spec_int (INDICATOR_POWER_DEVICE_KIND,
00082                                             "kind",
00083                                             "The device's UpDeviceKind",
00084                                             UP_DEVICE_KIND_UNKNOWN, UP_DEVICE_KIND_LAST,
00085                                             UP_DEVICE_KIND_UNKNOWN,
00086                                             G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
00087 
00088   properties[PROP_STATE] = g_param_spec_int (INDICATOR_POWER_DEVICE_STATE,
00089                                              "state",
00090                                              "The device's UpDeviceState",
00091                                              UP_DEVICE_STATE_UNKNOWN, UP_DEVICE_STATE_LAST,
00092                                              UP_DEVICE_STATE_UNKNOWN,
00093                                              G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
00094 
00095   properties[PROP_OBJECT_PATH] = g_param_spec_string (INDICATOR_POWER_DEVICE_OBJECT_PATH,
00096                                                       "object path",
00097                                                       "The device's DBus object path",
00098                                                       NULL,
00099                                                       G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
00100 
00101   properties[PROP_PERCENTAGE] = g_param_spec_double (INDICATOR_POWER_DEVICE_PERCENTAGE,
00102                                                      "percentage",
00103                                                      "percent charged",
00104                                                      0.0, 100.0,
00105                                                      0.0,
00106                                                      G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
00107 
00108   properties[PROP_TIME] = g_param_spec_uint64 (INDICATOR_POWER_DEVICE_TIME,
00109                                                "time",
00110                                                "time left",
00111                                                0, G_MAXUINT64,
00112                                                0,
00113                                                G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
00114 
00115   g_object_class_install_properties (object_class, N_PROPERTIES, properties);
00116 }
00117 
00118 /* Initialize an instance */
00119 static void
00120 indicator_power_device_init (IndicatorPowerDevice *self)
00121 {
00122   IndicatorPowerDevicePrivate * priv;
00123 
00124   priv = G_TYPE_INSTANCE_GET_PRIVATE (self, INDICATOR_POWER_DEVICE_TYPE,
00125                                             IndicatorPowerDevicePrivate);
00126   priv->kind = UP_DEVICE_KIND_UNKNOWN;
00127   priv->state = UP_DEVICE_STATE_UNKNOWN;
00128   priv->object_path = NULL;
00129   priv->percentage = 0.0;
00130   priv->time = 0;
00131 
00132   self->priv = priv;
00133 }
00134 
00135 static void
00136 indicator_power_device_dispose (GObject *object)
00137 {
00138   G_OBJECT_CLASS (indicator_power_device_parent_class)->dispose (object);
00139 }
00140 
00141 static void
00142 indicator_power_device_finalize (GObject *object)
00143 {
00144   IndicatorPowerDevice * self = INDICATOR_POWER_DEVICE(object);
00145   IndicatorPowerDevicePrivate * priv = self->priv;
00146 
00147   g_clear_pointer (&priv->object_path, g_free);
00148 
00149   G_OBJECT_CLASS (indicator_power_device_parent_class)->finalize (object);
00150 }
00151 
00152 /***
00153 ****
00154 ***/
00155 
00156 static void
00157 get_property (GObject * o, guint  prop_id, GValue * value, GParamSpec * pspec)
00158 {
00159   IndicatorPowerDevice * self = INDICATOR_POWER_DEVICE(o);
00160   IndicatorPowerDevicePrivate * priv = self->priv;
00161 
00162   switch (prop_id)
00163     {
00164       case PROP_KIND:
00165         g_value_set_int (value, priv->kind);
00166         break;
00167 
00168       case PROP_STATE:
00169         g_value_set_int (value, priv->state);
00170         break;
00171 
00172       case PROP_OBJECT_PATH:
00173         g_value_set_string (value, priv->object_path);
00174         break;
00175 
00176       case PROP_PERCENTAGE:
00177         g_value_set_double (value, priv->percentage);
00178         break;
00179 
00180       case PROP_TIME:
00181         g_value_set_uint64 (value, priv->time);
00182         break;
00183 
00184       default:
00185         G_OBJECT_WARN_INVALID_PROPERTY_ID(o, prop_id, pspec);
00186         break;
00187     }
00188 }
00189 
00190 static void
00191 set_property (GObject * o, guint prop_id, const GValue * value, GParamSpec * pspec)
00192 {
00193   IndicatorPowerDevice * self = INDICATOR_POWER_DEVICE(o);
00194   IndicatorPowerDevicePrivate * priv = self->priv;
00195 
00196   switch (prop_id)
00197     {
00198       case PROP_KIND:
00199         priv->kind = g_value_get_int (value);
00200         break;
00201 
00202       case PROP_STATE:
00203         priv->state = g_value_get_int (value);
00204         break;
00205 
00206       case PROP_OBJECT_PATH:
00207         g_free (priv->object_path);
00208         priv->object_path = g_value_dup_string (value);
00209         break;
00210 
00211       case PROP_PERCENTAGE:
00212         priv->percentage = g_value_get_double (value);
00213         break;
00214 
00215       case PROP_TIME:
00216         priv->time = g_value_get_uint64(value);
00217         break;
00218 
00219       default:
00220         G_OBJECT_WARN_INVALID_PROPERTY_ID(o, prop_id, pspec);
00221         break;
00222     }
00223 }
00224 
00225 /***
00226 ****  Accessors
00227 ***/
00228 
00229 UpDeviceKind
00230 indicator_power_device_get_kind  (const IndicatorPowerDevice * device)
00231 {
00232   /* LCOV_EXCL_START */
00233   g_return_val_if_fail (INDICATOR_IS_POWER_DEVICE(device), UP_DEVICE_KIND_UNKNOWN);
00234   /* LCOV_EXCL_STOP */
00235 
00236   return device->priv->kind;
00237 }
00238 
00239 UpDeviceState
00240 indicator_power_device_get_state (const IndicatorPowerDevice * device)
00241 {
00242   /* LCOV_EXCL_START */
00243   g_return_val_if_fail (INDICATOR_IS_POWER_DEVICE(device), UP_DEVICE_STATE_UNKNOWN);
00244   /* LCOV_EXCL_STOP */
00245 
00246   return device->priv->state;
00247 }
00248 
00249 const gchar *
00250 indicator_power_device_get_object_path (const IndicatorPowerDevice * device)
00251 {
00252   /* LCOV_EXCL_START */
00253   g_return_val_if_fail (INDICATOR_IS_POWER_DEVICE(device), NULL);
00254   /* LCOV_EXCL_STOP */
00255 
00256   return device->priv->object_path;
00257 }
00258 
00259 gdouble
00260 indicator_power_device_get_percentage (const IndicatorPowerDevice * device)
00261 {
00262   /* LCOV_EXCL_START */
00263   g_return_val_if_fail (INDICATOR_IS_POWER_DEVICE(device), 0.0);
00264   /* LCOV_EXCL_STOP */
00265 
00266   return device->priv->percentage;
00267 }
00268 
00269 time_t
00270 indicator_power_device_get_time (const IndicatorPowerDevice * device)
00271 {
00272   /* LCOV_EXCL_START */
00273   g_return_val_if_fail (INDICATOR_IS_POWER_DEVICE(device), (time_t)0);
00274   /* LCOV_EXCL_STOP */
00275 
00276   return device->priv->time;
00277 }
00278 
00279 /***
00280 ****
00281 ****
00282 ***/
00283 
00284 static const gchar *
00285 get_device_icon_suffix (gdouble percentage)
00286 {
00287   if (percentage >= 60) return "full";
00288   if (percentage >= 30) return "good";
00289   if (percentage >= 10) return "low";
00290   return "caution";
00291 }
00292 
00293 static const gchar *
00294 get_device_icon_index (gdouble percentage)
00295 {
00296   if (percentage >= 90) return "100";
00297   if (percentage >= 70) return "080";
00298   if (percentage >= 50) return "060";
00299   if (percentage >= 30) return "040";
00300   if (percentage >= 10) return "020";
00301   return "000";
00302 }
00303 
00324 GStrv
00325 indicator_power_device_get_icon_names (const IndicatorPowerDevice * device)
00326 {
00327   const gchar *suffix_str;
00328   const gchar *index_str;
00329 
00330   /* LCOV_EXCL_START */
00331   g_return_val_if_fail (INDICATOR_IS_POWER_DEVICE(device), NULL);
00332   /* LCOV_EXCL_STOP */
00333 
00334   gdouble percentage = indicator_power_device_get_percentage (device);
00335   const UpDeviceKind kind = indicator_power_device_get_kind (device);
00336   const UpDeviceState state = indicator_power_device_get_state (device);
00337   const gchar * kind_str = kind_str = up_device_kind_to_string (kind);
00338 
00339   GPtrArray * names = g_ptr_array_new ();
00340 
00341   if (kind == UP_DEVICE_KIND_LINE_POWER)
00342     {
00343       g_ptr_array_add (names, g_strdup("ac-adapter-symbolic"));
00344       g_ptr_array_add (names, g_strdup("ac-adapter"));
00345     }
00346   else if (kind == UP_DEVICE_KIND_MONITOR)
00347     {
00348       g_ptr_array_add (names, g_strdup("gpm-monitor-symbolic"));
00349       g_ptr_array_add (names, g_strdup("gpm-monitor"));
00350     }
00351   else switch (state)
00352     {
00353       case UP_DEVICE_STATE_EMPTY:
00354         g_ptr_array_add (names, g_strdup("battery-empty-symbolic"));
00355         g_ptr_array_add (names, g_strdup_printf("gpm-%s-empty", kind_str));
00356         g_ptr_array_add (names, g_strdup_printf("gpm-%s-000", kind_str));
00357         g_ptr_array_add (names, g_strdup("battery-empty"));
00358         break;
00359 
00360       case UP_DEVICE_STATE_FULLY_CHARGED:
00361         g_ptr_array_add (names, g_strdup("battery-full-charged-symbolic"));
00362         g_ptr_array_add (names, g_strdup("battery-full-charging-symbolic"));
00363         g_ptr_array_add (names, g_strdup_printf("gpm-%s-full", kind_str));
00364         g_ptr_array_add (names, g_strdup_printf("gpm-%s-100", kind_str));
00365         g_ptr_array_add (names, g_strdup("battery-full-charged"));
00366         g_ptr_array_add (names, g_strdup("battery-full-charging"));
00367         break;
00368 
00369       case UP_DEVICE_STATE_CHARGING:
00370       case UP_DEVICE_STATE_PENDING_CHARGE:
00371         /* When charging, always use the same icon regardless of percentage.
00372            <http://bugs.launchpad.net/indicator-power/+bug/824629> */
00373         percentage = 0;
00374 
00375         suffix_str = get_device_icon_suffix (percentage);
00376         index_str = get_device_icon_index (percentage);
00377         g_ptr_array_add (names, g_strdup_printf ("battery-%s-charging-symbolic", suffix_str));
00378         g_ptr_array_add (names, g_strdup_printf ("gpm-%s-%s-charging", kind_str, index_str));
00379         g_ptr_array_add (names, g_strdup_printf ("battery-%s-charging", suffix_str));
00380         break;
00381 
00382       case UP_DEVICE_STATE_DISCHARGING:
00383       case UP_DEVICE_STATE_PENDING_DISCHARGE:
00384         /* Don't show the caution/red icons unless we have <=30 min left.
00385            <https://bugs.launchpad.net/indicator-power/+bug/743823>
00386            Themes use the caution color when the percentage is 0% or 20%,
00387            so if we have >30 min left, use 30% as the icon's percentage floor */
00388         if (indicator_power_device_get_time (device) > (30*60))
00389           percentage = MAX(percentage, 30);
00390 
00391         suffix_str = get_device_icon_suffix (percentage);
00392         index_str = get_device_icon_index (percentage);
00393         g_ptr_array_add (names, g_strdup_printf ("battery-%s-symbolic", suffix_str));
00394         g_ptr_array_add (names, g_strdup_printf ("gpm-%s-%s", kind_str, index_str));
00395         g_ptr_array_add (names, g_strdup_printf ("battery-%s", suffix_str));
00396         break;
00397 
00398       default:
00399         g_ptr_array_add (names, g_strdup("battery-missing-symbolic"));
00400         g_ptr_array_add (names, g_strdup("gpm-battery-missing"));
00401         g_ptr_array_add (names, g_strdup("battery-missing"));
00402     }
00403 
00404     g_ptr_array_add (names, NULL); /* terminates the strv */
00405     return (GStrv) g_ptr_array_free (names, FALSE);
00406 }
00407 
00417 GIcon *
00418 indicator_power_device_get_gicon (const IndicatorPowerDevice * device)
00419 {
00420   GStrv names = indicator_power_device_get_icon_names (device);
00421   GIcon * icon = g_themed_icon_new_from_names (names, -1);
00422   g_strfreev (names);
00423   return icon;
00424 }
00425 
00426 /***
00427 ****
00428 ***/
00429 
00430 static void
00431 get_timestring (guint64   time_secs,
00432                 gchar   **short_timestring,
00433                 gchar   **detailed_timestring)
00434 {
00435   gint  hours;
00436   gint  minutes;
00437 
00438   /* Add 0.5 to do rounding */
00439   minutes = (int) ( ( time_secs / 60.0 ) + 0.5 );
00440 
00441   if (minutes == 0)
00442     {
00443       *short_timestring = g_strdup (_("Unknown time"));
00444       *detailed_timestring = g_strdup (_("Unknown time"));
00445 
00446       return;
00447     }
00448 
00449   if (minutes < 60)
00450     {
00451       *short_timestring = g_strdup_printf ("0:%.2i", minutes);
00452       *detailed_timestring = g_strdup_printf (g_dngettext (GETTEXT_PACKAGE, "%i minute",
00453                                               "%i minutes",
00454                                               minutes), minutes);
00455       return;
00456     }
00457 
00458   hours = minutes / 60;
00459   minutes = minutes % 60;
00460 
00461   *short_timestring = g_strdup_printf ("%i:%.2i", hours, minutes);
00462 
00463   if (minutes == 0)
00464     {
00465       *detailed_timestring = g_strdup_printf (g_dngettext (GETTEXT_PACKAGE, 
00466                                               "%i hour",
00467                                               "%i hours",
00468                                               hours), hours);
00469     }
00470   else
00471     {
00472       /* TRANSLATOR: "%i %s %i %s" are "%i hours %i minutes"
00473        * Swap order with "%2$s %2$i %1$s %1$i if needed */
00474       *detailed_timestring = g_strdup_printf (_("%i %s %i %s"),
00475                                               hours, g_dngettext (GETTEXT_PACKAGE, "hour", "hours", hours),
00476                                               minutes, g_dngettext (GETTEXT_PACKAGE, "minute", "minutes", minutes));
00477     }
00478 }
00479 
00480 static const gchar *
00481 device_kind_to_localised_string (UpDeviceKind kind)
00482 {
00483   const gchar *text = NULL;
00484 
00485   switch (kind) {
00486     case UP_DEVICE_KIND_LINE_POWER:
00487       /* TRANSLATORS: system power cord */
00488       text = _("AC Adapter");
00489       break;
00490     case UP_DEVICE_KIND_BATTERY:
00491       /* TRANSLATORS: laptop primary battery */
00492       text = _("Battery");
00493       break;
00494     case UP_DEVICE_KIND_UPS:
00495       /* TRANSLATORS: battery-backed AC power source */
00496       text = _("UPS");
00497       break;
00498     case UP_DEVICE_KIND_MONITOR:
00499       /* TRANSLATORS: a monitor is a device to measure voltage and current */
00500       text = _("Monitor");
00501       break;
00502     case UP_DEVICE_KIND_MOUSE:
00503       /* TRANSLATORS: wireless mice with internal batteries */
00504       text = _("Mouse");
00505       break;
00506     case UP_DEVICE_KIND_KEYBOARD:
00507       /* TRANSLATORS: wireless keyboard with internal battery */
00508       text = _("Keyboard");
00509       break;
00510     case UP_DEVICE_KIND_PDA:
00511       /* TRANSLATORS: portable device */
00512       text = _("PDA");
00513       break;
00514     case UP_DEVICE_KIND_PHONE:
00515       /* TRANSLATORS: cell phone (mobile...) */
00516       text = _("Cell phone");
00517       break;
00518     case UP_DEVICE_KIND_MEDIA_PLAYER:
00519       /* TRANSLATORS: media player, mp3 etc */
00520       text = _("Media player");
00521       break;
00522     case UP_DEVICE_KIND_TABLET:
00523       /* TRANSLATORS: tablet device */
00524       text = _("Tablet");
00525       break;
00526     case UP_DEVICE_KIND_COMPUTER:
00527       /* TRANSLATORS: tablet device */
00528       text = _("Computer");
00529       break;
00530     default:
00531       g_warning ("enum unrecognised: %i", kind);
00532       text = up_device_kind_to_string (kind);
00533     }
00534 
00535   return text;
00536 }
00537 
00538 void
00539 indicator_power_device_get_time_details (const IndicatorPowerDevice * device,
00540                                          gchar ** short_details,
00541                                          gchar ** details,
00542                                          gchar ** accessible_name)
00543 {
00544   if (!INDICATOR_IS_POWER_DEVICE(device))
00545     {
00546       *short_details = NULL;
00547       *details = NULL;
00548       *accessible_name = NULL;
00549       g_warning ("%s: %p is not an IndicatorPowerDevice", G_STRFUNC, device);
00550       return;
00551     }
00552 
00553   const time_t time = indicator_power_device_get_time (device);
00554   const UpDeviceState state = indicator_power_device_get_state (device);
00555   const gdouble percentage = indicator_power_device_get_percentage (device);
00556   const UpDeviceKind kind = indicator_power_device_get_kind (device);
00557   const gchar * device_name = device_kind_to_localised_string (kind);
00558 
00559   if (time > 0)
00560     {
00561       gchar *short_timestring = NULL;
00562       gchar *detailed_timestring = NULL;
00563 
00564       get_timestring (time,
00565                       &short_timestring,
00566                       &detailed_timestring);
00567 
00568       if (state == UP_DEVICE_STATE_CHARGING)
00569         {
00570           /* TRANSLATORS: %2 is a time string, e.g. "1 hour 5 minutes" */
00571           *accessible_name = g_strdup_printf (_("%s (%s to charge (%.0lf%%))"), device_name, detailed_timestring, percentage);
00572           *details = g_strdup_printf (_("%s (%s to charge)"), device_name, short_timestring);
00573           *short_details = g_strdup_printf ("(%s)", short_timestring);
00574         }
00575       else if ((state == UP_DEVICE_STATE_DISCHARGING) && (time > (60*60*12)))
00576         {
00577           *accessible_name = g_strdup_printf (_("%s"), device_name);
00578           *details = g_strdup_printf (_("%s"), device_name);
00579           *short_details = g_strdup (short_timestring);
00580         }
00581       else
00582         {
00583           /* TRANSLATORS: %2 is a time string, e.g. "1 hour 5 minutes" */
00584           *accessible_name = g_strdup_printf (_("%s (%s left (%.0lf%%))"), device_name, detailed_timestring, percentage);
00585           *details = g_strdup_printf (_("%s (%s left)"), device_name, short_timestring);
00586           *short_details = g_strdup (short_timestring);
00587         }
00588 
00589       g_free (short_timestring);
00590       g_free (detailed_timestring);
00591     }
00592   else if (state == UP_DEVICE_STATE_FULLY_CHARGED)
00593     {
00594       *details = g_strdup_printf (_("%s (charged)"), device_name);
00595       *accessible_name = g_strdup (*details);
00596       *short_details = g_strdup ("");
00597     }
00598   else if (percentage > 0)
00599     {
00600       /* TRANSLATORS: %2 is a percentage value. Note: this string is only
00601        * used when we don't have a time value */
00602       *details = g_strdup_printf (_("%s (%.0lf%%)"), device_name, percentage);
00603       *accessible_name = g_strdup (*details);
00604       *short_details = g_strdup_printf (_("(%.0lf%%)"), percentage);
00605     }
00606   else if (kind == UP_DEVICE_KIND_LINE_POWER)
00607     {
00608       *details         = g_strdup (device_name);
00609       *accessible_name = g_strdup (device_name);
00610       *short_details   = g_strdup (device_name);
00611     }
00612   else
00613     {
00614       *details = g_strdup_printf (_("%s (not present)"), device_name);
00615       *accessible_name = g_strdup (*details);
00616       *short_details = g_strdup (_("(not present)"));
00617     }
00618 }
00619 
00620 /***
00621 ****  Instantiation
00622 ***/
00623 
00624 IndicatorPowerDevice *
00625 indicator_power_device_new (const gchar * object_path,
00626                             UpDeviceKind  kind,
00627                             gdouble percentage,
00628                             UpDeviceState state,
00629                             time_t timestamp)
00630 {
00631   GObject * o = g_object_new (INDICATOR_POWER_DEVICE_TYPE,
00632     INDICATOR_POWER_DEVICE_KIND, kind,
00633     INDICATOR_POWER_DEVICE_STATE, state,
00634     INDICATOR_POWER_DEVICE_OBJECT_PATH, object_path,
00635     INDICATOR_POWER_DEVICE_PERCENTAGE, percentage,
00636     INDICATOR_POWER_DEVICE_TIME, (guint64)timestamp,
00637     NULL);
00638   return INDICATOR_POWER_DEVICE(o);
00639 }
00640 
00641 IndicatorPowerDevice *
00642 indicator_power_device_new_from_variant (GVariant * v)
00643 {
00644   g_return_val_if_fail (g_variant_is_of_type (v, G_VARIANT_TYPE("(susdut)")), NULL);
00645 
00646   UpDeviceKind kind = UP_DEVICE_KIND_UNKNOWN;
00647   UpDeviceState state = UP_DEVICE_STATE_UNKNOWN;
00648   const gchar * icon = NULL;
00649   const gchar * object_path = NULL;
00650   gdouble percentage = 0;
00651   guint64 time = 0;
00652 
00653   g_variant_get (v, "(&su&sdut)",
00654                  &object_path,
00655                  &kind,
00656                  &icon,
00657                  &percentage,
00658                  &state,
00659                  &time);
00660 
00661   return indicator_power_device_new (object_path,
00662                                      kind,
00663                                      percentage,
00664                                      state,
00665                                      time);
00666 }