]> git.ipfire.org Git - thirdparty/plymouth.git/commitdiff
Move boot time accounting up a layer
authorRay Strode <rstrode@redhat.com>
Thu, 25 Sep 2008 04:45:38 +0000 (00:45 -0400)
committerRay Strode <rstrode@redhat.com>
Mon, 29 Sep 2008 03:40:27 +0000 (23:40 -0400)
This way all plugins can access it as a standard feature.
We'll need to move it a layer higher still, though, to
make sure progress bars don't get reset when the user
presses escape twice, etc (it's per-boot state, not
per-splash state).

src/Makefile.am
src/libplybootsplash/ply-boot-splash-plugin.h
src/plugins/splash/spinfinity/plugin.c
src/ply-boot-splash.c

index 8857487007fd5ce093fd6a3d4029ed55327f78ad..09eeb5b7db792ffb855d6c3f0fd51b0288d02e1e 100644 (file)
@@ -4,6 +4,7 @@ INCLUDES = -I$(top_srcdir)                                                    \
            -I$(srcdir)/libplybootsplash                                       \
            -I$(srcdir)                                                        \
            -DPLYMOUTH_LOG_DIRECTORY=\"$(localstatedir)/log\"                  \
+           -DPLYMOUTH_TIME_DIRECTORY=\"$(localstatedir)/lib/plymouth/\"       \
            -DPLYMOUTH_SPOOL_DIRECTORY=\"$(localstatedir)/spool/plymouth\"     \
            -DPLYMOUTH_LOGO_FILE=\"$(logofile)\"
 
index 458cfc9de4f5a38f2cddc23fd7b3e3406b4c65a7..cf16f688828a32b8c514ea0a06677400763180f7 100644 (file)
@@ -53,6 +53,9 @@ typedef struct
   void (* on_boot_output) (ply_boot_splash_plugin_t *plugin,
                            const char               *output,
                            size_t                    size);
+  void (* on_boot_progress) (ply_boot_splash_plugin_t *plugin,
+                             double                    duration,
+                             double                    percent_done);
   void (* on_root_mounted) (ply_boot_splash_plugin_t *plugin);
   void (* hide_splash_screen) (ply_boot_splash_plugin_t *plugin,
                                ply_event_loop_t         *loop);
index 02acb68baddd5f488c94625d698b439467570234..e466c08214a9e4d20fd7a98311ff6ee7494327c1 100644 (file)
 #define BAR_HEIGHT 16
 #endif
 
-#ifndef DEFAULT_BOOT_DURATION
-#define DEFAULT_BOOT_DURATION 45.0
-#endif
-
-#define BOOTTIME_FILE PLYMOUTH_TIME_DIR "/boot-time"
-
 struct _ply_boot_splash_plugin
 {
   ply_event_loop_t *loop;
@@ -87,10 +81,6 @@ struct _ply_boot_splash_plugin
   ply_label_t *label;
   ply_progress_bar_t *progress_bar;
 
-  double boot_duration;
-  double start_time;
-  double wait_time;
-
   ply_trigger_t *pending_password_answer;
   ply_trigger_t *idle_trigger;
 
@@ -102,7 +92,6 @@ static void detach_from_event_loop (ply_boot_splash_plugin_t *plugin);
 ply_boot_splash_plugin_t *
 create_plugin (void)
 {
-  FILE *fh;
   ply_boot_splash_plugin_t *plugin;
 
   srand ((int) ply_get_timestamp ());
@@ -118,18 +107,6 @@ create_plugin (void)
   plugin->label = ply_label_new ();
   plugin->progress_bar = ply_progress_bar_new ();
 
-  plugin->start_time = ply_get_timestamp ();
-  plugin->boot_duration = DEFAULT_BOOT_DURATION;
-  /* We should be reading from the initrd at this point */
-  fh = fopen(BOOTTIME_FILE,"r"); 
-  if (fh != NULL) {
-      int r;
-      r = fscanf (fh,"%lf",&plugin->boot_duration);
-      /* Don't need to check the return value - if this failed we still have
-       * the default BOOTTIME value, which was set above */
-      fclose (fh);
-  }
-
   return plugin;
 }
 
@@ -147,11 +124,9 @@ tell_gdm_to_transition (void)
 void
 destroy_plugin (ply_boot_splash_plugin_t *plugin)
 {
-  FILE *boot_duration;
   if (plugin == NULL)
     return;
 
-
   if (plugin->loop != NULL)
     {
       ply_event_loop_stop_watching_for_exit (plugin->loop, (ply_event_loop_exit_handler_t)
@@ -168,14 +143,6 @@ destroy_plugin (ply_boot_splash_plugin_t *plugin)
   ply_label_free (plugin->label);
   ply_progress_bar_free (plugin->progress_bar);
 
-  ply_trace ("writing boot_duration");
-  /* At this point we should have a real rootfs */
-  boot_duration = fopen (BOOTTIME_FILE,"w");
-  if (boot_duration != NULL) { 
-    fprintf (boot_duration,"%.1f\n", (ply_get_timestamp () - plugin->start_time));
-    fclose (boot_duration);
-  }
-
 #ifdef PLY_ENABLE_GDM_TRANSITION
   if (plugin->is_visible)
     tell_gdm_to_transition ();
@@ -223,30 +190,6 @@ draw_logo (ply_boot_splash_plugin_t *plugin)
   ply_frame_buffer_unpause_updates (plugin->frame_buffer);
 }
 
-static void
-animate_bar (ply_boot_splash_plugin_t *plugin)
-{
-  double duration;
-  double percent_done;
-
-  assert (plugin != NULL);
-  assert (plugin->loop != NULL);
-
-  duration = ply_get_timestamp () - plugin->start_time;
-
-  /* Fun made-up smoothing function to make the growth asymptotic:
-   * fraction(time,estimate)=1-2^(-(time^1.45)/estimate) */
-  percent_done = 1.0 - pow (2.0, -pow (duration, 1.45) / plugin->boot_duration);
-
-  ply_progress_bar_set_percent_done (plugin->progress_bar, percent_done);
-  ply_progress_bar_draw (plugin->progress_bar);
-
-  ply_event_loop_watch_for_timeout(plugin->loop,
-                                   1.0 / FRAMES_PER_SECOND,
-                                   (ply_event_loop_timeout_handler_t)
-                                   animate_bar, plugin);
-}
-
 static void
 start_animation (ply_boot_splash_plugin_t *plugin)
 {
@@ -271,7 +214,6 @@ start_animation (ply_boot_splash_plugin_t *plugin)
   ply_progress_bar_show (plugin->progress_bar,
                          plugin->window,
                          0, area.height - ply_progress_bar_get_height (plugin->progress_bar));
-  animate_bar (plugin);
 }
 
 static void
@@ -284,9 +226,6 @@ stop_animation (ply_boot_splash_plugin_t *plugin,
   assert (plugin->loop != NULL);
 
   ply_throbber_stop (plugin->throbber, trigger);
-  ply_event_loop_stop_watching_for_timeout(plugin->loop,
-                                           (ply_event_loop_timeout_handler_t)
-                                           animate_bar, plugin); 
 
 #ifdef ENABLE_FADE_OUT
   for (i = 0; i < 10; i++)
@@ -353,7 +292,6 @@ on_enter (ply_boot_splash_plugin_t *plugin,
 
   ply_entry_hide (plugin->entry);
   ply_entry_remove_all_bullets (plugin->entry);
-  plugin->start_time += (ply_get_timestamp() - plugin->wait_time);
   start_animation (plugin);
 }
 
@@ -498,6 +436,23 @@ update_status (ply_boot_splash_plugin_t *plugin,
   assert (plugin != NULL);
 }
 
+void
+on_boot_progress (ply_boot_splash_plugin_t *plugin,
+                  double                    duration,
+                  double                    percent_done)
+{
+  double total_duration;
+
+  total_duration = duration / percent_done;
+
+  /* Fun made-up smoothing function to make the growth asymptotic:
+   * fraction(time,estimate)=1-2^(-(time^1.45)/estimate) */
+  percent_done = 1.0 - pow (2.0, -pow (duration, 1.45) / total_duration);
+
+  ply_progress_bar_set_percent_done (plugin->progress_bar, percent_done);
+  ply_progress_bar_draw (plugin->progress_bar);
+}
+
 void
 hide_splash_screen (ply_boot_splash_plugin_t *plugin,
                     ply_event_loop_t         *loop)
@@ -598,7 +553,6 @@ ask_for_password (ply_boot_splash_plugin_t *plugin,
                   ply_trigger_t            *answer)
 {
   plugin->pending_password_answer = answer;
-  plugin->wait_time = ply_get_timestamp ();
 
   if (ply_entry_is_hidden (plugin->entry))
     {
@@ -636,10 +590,11 @@ ply_boot_splash_plugin_get_interface (void)
       .remove_window = remove_window,
       .show_splash_screen = show_splash_screen,
       .update_status = update_status,
+      .on_boot_progress = on_boot_progress,
       .hide_splash_screen = hide_splash_screen,
       .ask_for_password = ask_for_password,
       .on_root_mounted = on_root_mounted,
-      .become_idle = become_idle
+      .become_idle = become_idle,
     };
 
   return &plugin_interface;
index 832491e6a1ed031df542c3e4a1ac49920c8b08a4..408e5c7ddaedaddca8332d45b39bdf9bd3711bfa 100644 (file)
 #include "ply-trigger.h"
 #include "ply-utils.h"
 
+#ifndef UPDATES_PER_SECOND
+#define UPDATES_PER_SECOND 30
+#endif
+
+#ifndef DEFAULT_BOOT_DURATION
+#define DEFAULT_BOOT_DURATION 45.0
+#endif
+
+#define BOOT_DURATION_FILE PLYMOUTH_TIME_DIRECTORY "/boot-duration"
+
 struct _ply_boot_splash
 {
   ply_event_loop_t *loop;
@@ -52,6 +62,10 @@ struct _ply_boot_splash
   char *module_name;
   char *status;
 
+  double boot_duration;
+  double start_time;
+  double wait_time;
+
   uint32_t is_shown : 1;
 };
 
@@ -123,6 +137,39 @@ ply_boot_splash_load_plugin (ply_boot_splash_t *splash)
   return true;
 }
 
+static void
+load_boot_duration (ply_boot_splash_t *splash)
+{
+  FILE *fp;
+  int items_matched;
+
+  fp = fopen (BOOT_DURATION_FILE,"r"); 
+
+  if (fp == NULL)
+    return;
+
+  items_matched = fscanf (fp, "%lf", &splash->boot_duration);
+
+  fclose (fp);
+
+  if (items_matched != 1)
+    splash->boot_duration = DEFAULT_BOOT_DURATION;
+}
+
+static void
+save_boot_duration (ply_boot_splash_t *splash)
+{
+  FILE *fp;
+
+  fp = fopen (BOOT_DURATION_FILE,"w");
+
+  if (fp != NULL)
+    {
+      fprintf (fp, "%.1f\n", (ply_get_timestamp () - splash->start_time));
+      fclose (fp);
+    }
+}
+
 static void
 ply_boot_splash_unload_plugin (ply_boot_splash_t *splash)
 {
@@ -137,6 +184,8 @@ ply_boot_splash_unload_plugin (ply_boot_splash_t *splash)
   ply_close_module (splash->module_handle);
   splash->plugin_interface = NULL;
   splash->module_handle = NULL;
+
+  save_boot_duration (splash);
 }
 
 void
@@ -152,6 +201,26 @@ ply_boot_splash_free (ply_boot_splash_t *splash)
   free (splash);
 }
 
+static void
+ply_boot_splash_update_progress (ply_boot_splash_t *splash)
+{
+  double time_in_seconds;
+
+  assert (splash != NULL);
+
+  time_in_seconds = ply_get_timestamp () - splash->start_time;
+
+  if (splash->plugin_interface->on_boot_progress != NULL)
+    splash->plugin_interface->on_boot_progress (splash->plugin,
+                                                time_in_seconds,
+                                                time_in_seconds / splash->boot_duration);
+
+  ply_event_loop_watch_for_timeout (splash->loop,
+                                   1.0 / UPDATES_PER_SECOND,
+                                   (ply_event_loop_timeout_handler_t)
+                                   ply_boot_splash_update_progress, splash);
+}
+
 bool
 ply_boot_splash_show (ply_boot_splash_t *splash)
 {
@@ -162,6 +231,9 @@ ply_boot_splash_show (ply_boot_splash_t *splash)
   if (splash->is_shown)
     return true;
 
+  splash->start_time = ply_get_timestamp ();
+  splash->boot_duration = DEFAULT_BOOT_DURATION;
+
   ply_trace ("trying to load %s", splash->module_name);
   if (!ply_boot_splash_load_plugin (splash))
     {
@@ -189,6 +261,14 @@ ply_boot_splash_show (ply_boot_splash_t *splash)
       return false;
     }
 
+  if (splash->plugin_interface->on_boot_progress != NULL)
+    {
+      ply_event_loop_watch_for_timeout (splash->loop,
+                                        1.0 / UPDATES_PER_SECOND,
+                                        (ply_event_loop_timeout_handler_t)
+                                        ply_boot_splash_update_progress, splash);
+    }
+
   splash->is_shown = true;
   return true;
 }
@@ -226,6 +306,15 @@ ply_boot_splash_root_mounted (ply_boot_splash_t *splash)
 
   if (splash->plugin_interface->on_root_mounted != NULL)
     splash->plugin_interface->on_root_mounted (splash->plugin);
+
+  if (splash->plugin_interface->on_boot_progress != NULL)
+    load_boot_duration (splash);
+}
+
+static void
+on_password_answered (ply_boot_splash_t *splash)
+{
+  splash->start_time += (ply_get_timestamp () - splash->wait_time);
 }
 
 void
@@ -245,6 +334,11 @@ ply_boot_splash_ask_for_password (ply_boot_splash_t *splash,
       return;
     }
 
+  splash->wait_time = ply_get_timestamp ();
+  ply_trigger_add_handler (trigger,
+                           (ply_trigger_handler_t)
+                           on_password_answered, splash);
+
   splash->plugin_interface->ask_for_password (splash->plugin,
                                               prompt,
                                               trigger);
@@ -274,6 +368,13 @@ ply_boot_splash_hide (ply_boot_splash_t *splash)
 
   if (splash->loop != NULL)
     {
+      if (splash->plugin_interface->on_boot_progress != NULL)
+        {
+          ply_event_loop_stop_watching_for_timeout (splash->loop,
+                                                    (ply_event_loop_timeout_handler_t)
+                                                    ply_boot_splash_update_progress, splash);
+        }
+
       ply_event_loop_stop_watching_for_exit (splash->loop, (ply_event_loop_exit_handler_t)
                                              ply_boot_splash_detach_from_event_loop,
                                              splash);