diff mbox

[6/7] s3power.c: add support for logind and sysfs methods

Message ID 1406803669-12439-7-git-send-email-alberto.milone@canonical.com
State Superseded
Headers show

Commit Message

Alberto Milone July 31, 2014, 10:47 a.m. UTC
As with s3.c, we now make use of different power methods and default
to logind, leaving pm-utils as an option.
---
 src/acpi/s3power/s3power.c | 121 ++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 113 insertions(+), 8 deletions(-)
diff mbox

Patch

diff --git a/src/acpi/s3power/s3power.c b/src/acpi/s3power/s3power.c
index f332aae..275539c 100644
--- a/src/acpi/s3power/s3power.c
+++ b/src/acpi/s3power/s3power.c
@@ -19,6 +19,7 @@ 
 #include <getopt.h>
 
 #include "fwts.h"
+#include "fwts_pm_method.h"
 
 #ifdef FWTS_ARCH_INTEL
 
@@ -114,6 +115,78 @@  static int s3power_init(fwts_framework *fw)
 	return FWTS_OK;
 }
 
+/* Detect the best available power method */
+static void detect_pm_method(fwts_pm_method_vars *fwts_settings)
+{
+	if (fwts_logind_can_suspend(fwts_settings))
+		fwts_settings->fw->pm_method = FWTS_PM_LOGIND;
+	else if (fwts_sysfs_can_suspend(fwts_settings))
+		fwts_settings->fw->pm_method = FWTS_PM_SYSFS;
+	else
+		fwts_settings->fw->pm_method = FWTS_PM_PMUTILS;
+}
+
+static int wrap_logind_do_suspend(fwts_pm_method_vars *fwts_settings,
+	const int percent,
+	int *duration,
+	const char *str)
+{
+	FWTS_UNUSED(str);
+
+	fwts_progress_message(fwts_settings->fw, percent, "(Suspending)");
+	/* This blocks by entering a glib mainloop */
+	*duration = fwts_logind_wait_for_resume_from_action(fwts_settings, PM_SUSPEND_LOGIND, 0);
+	fwts_log_info(fwts_settings->fw, "S3 duration = %d.", *duration);
+	fwts_progress_message(fwts_settings->fw, percent, "(Resumed)");
+
+	return *duration > 0 ? 0 : 1;
+}
+
+static int wrap_sysfs_do_suspend(fwts_pm_method_vars *fwts_settings,
+	const int percent,
+	int *duration,
+	const char *str)
+{
+	int status;
+
+	FWTS_UNUSED(str);
+	fwts_progress_message(fwts_settings->fw, percent, "(Suspending)");
+	time(&(fwts_settings->t_start));
+	(void)fwts_klog_write(fwts_settings->fw, "Starting fwts suspend\n");
+	(void)fwts_klog_write(fwts_settings->fw, FWTS_SUSPEND "\n");
+	status = fwts_sysfs_do_suspend(fwts_settings, false);
+	(void)fwts_klog_write(fwts_settings->fw, FWTS_RESUME "\n");
+	(void)fwts_klog_write(fwts_settings->fw, "Finished fwts resume\n");
+	time(&(fwts_settings->t_end));
+	fwts_progress_message(fwts_settings->fw, percent, "(Resumed)");
+
+	*duration = (int)(fwts_settings->t_end - fwts_settings->t_start);
+
+	return status;
+}
+
+static int wrap_pmutils_do_suspend(fwts_pm_method_vars *fwts_settings,
+	const int percent,
+	int *duration,
+	const char *command)
+{
+	int status;
+
+	fwts_progress_message(fwts_settings->fw, percent, "(Suspending)");
+	time(&(fwts_settings->t_start));
+	(void)fwts_klog_write(fwts_settings->fw, "Starting fwts suspend\n");
+	(void)fwts_klog_write(fwts_settings->fw, FWTS_SUSPEND "\n");
+	(void)fwts_exec(command, &status);
+	(void)fwts_klog_write(fwts_settings->fw, FWTS_RESUME "\n");
+	(void)fwts_klog_write(fwts_settings->fw, "Finished fwts resume\n");
+	time(&(fwts_settings->t_end));
+	fwts_progress_message(fwts_settings->fw, percent, "(Resumed)");
+
+	*duration = (int)(fwts_settings->t_end - fwts_settings->t_start);
+
+	return status;
+}
+
 static void s3power_difference(fwts_framework *fw,
 	uint32_t before, uint32_t after,
 	uint32_t battery_capacity, char *units)
@@ -163,8 +236,6 @@  static int s3power_test(fwts_framework *fw)
 	int status;
 	int duration;
 
-	time_t t_start;
-	time_t t_end;
 	bool offline;
 
 	uint32_t capacity_before_mAh;
@@ -172,6 +243,45 @@  static int s3power_test(fwts_framework *fw)
 	uint32_t capacity_before_mWh;
 	uint32_t capacity_after_mWh;
 
+	_cleanup_free_pm_vars_ fwts_pm_method_vars * fwts_settings = NULL;
+
+	int (*do_suspend)(fwts_pm_method_vars *, const int, int*, const char*);
+
+	fwts_settings = calloc(1, sizeof(fwts_pm_method_vars));
+	if (fwts_settings == NULL)
+		return FWTS_OUT_OF_MEMORY;
+	fwts_settings->fw = fw;
+
+	if (fw->pm_method == FWTS_PM_UNDEFINED) {
+		/* Autodetection */
+		fwts_log_info(fw, "Detecting the power method.");
+		detect_pm_method(fwts_settings);
+	}
+
+	switch (fw->pm_method) {
+		case FWTS_PM_LOGIND:
+			fwts_log_info(fw, "Using logind as the default power method.");
+			if (fwts_logind_init_proxy(fwts_settings) != 0) {
+				fwts_log_error(fw, "Failure to connect to Logind.");
+				return FWTS_ERROR;
+			}
+			do_suspend = &wrap_logind_do_suspend;
+			break;
+		case FWTS_PM_PMUTILS:
+			fwts_log_info(fw, "Using pm-utils as the default power method.");
+			do_suspend = &wrap_pmutils_do_suspend;
+			break;
+		case FWTS_PM_SYSFS:
+			fwts_log_info(fw, "Using sysfs as the default power method.");
+			do_suspend = &wrap_sysfs_do_suspend;
+			break;
+		default:
+			/* This should never happen */
+			fwts_log_info(fw, "Using sysfs as the default power method.");
+			do_suspend = &wrap_sysfs_do_suspend;
+			break;
+	}
+
 	if (s3power_wait_for_adapter_offline(fw, &offline) == FWTS_ERROR) {
 		fwts_log_error(fw, "Cannot check if machine is running on battery, aborting test.");
 		return FWTS_ABORTED;
@@ -186,18 +296,13 @@  static int s3power_test(fwts_framework *fw)
 	fwts_wakealarm_trigger(fw, s3power_sleep_delay);
 
 	/* Do S3 here */
-	fwts_progress_message(fw, 100, "(Suspending)");
-	time(&t_start);
-	(void)fwts_exec(PM_SUSPEND, &status);
-	time(&t_end);
-	fwts_progress_message(fw, 100, "(Resumed)");
+	status = do_suspend(fwts_settings, 100, &duration, PM_SUSPEND);
 
 	s3power_get_remaining_capacity(fw, &capacity_after_mAh, &capacity_after_mWh);
 
 	s3power_difference(fw, capacity_before_mAh, capacity_after_mAh, battery_capacity_mAh, "mAh");
 	s3power_difference(fw, capacity_before_mWh, capacity_after_mWh, battery_capacity_mWh, "mWh");
 
-	duration = (int)(t_end - t_start);
 	fwts_log_info(fw, "pm-suspend returned %d after %d seconds.", status, duration);
 
 	if (duration < s3power_sleep_delay)