diff -Nru powerd-0.5bzr9raring0/CMakeLists.txt powerd-0.12/CMakeLists.txt
--- powerd-0.5bzr9raring0/CMakeLists.txt 2013-03-21 13:44:57.000000000 +0000
+++ powerd-0.12/CMakeLists.txt 2013-06-03 17:17:09.000000000 +0000
@@ -1,39 +1,91 @@
project(powerd)
+cmake_minimum_required(VERSION 2.8.9)
-set(
- SRCS
+set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake" "${CMAKE_MODULE_PATH}")
+set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O0 -ggdb -g")
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O0 -ggdb -g")
- src/powerd.cpp
-)
+set(GDBUS_NAME powerd-dbus)
find_package(PkgConfig)
pkg_check_modules(GLIB glib-2.0)
pkg_check_modules(GUDEV gudev-1.0)
+pkg_check_modules(GIO gio-2.0)
+pkg_check_modules(GIO-UNIX gio-unix-2.0)
+pkg_check_modules(UUID uuid)
+
+set(POWERD_GENERATED_SOURCES
+ ${GDBUS_NAME}.c
+)
+set(POWERD_GENERATED_HEADERS
+ ${GDBUS_NAME}.h
+)
+SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/src/${POWERD_GENERATED_SOURCES} PROPERTIES GENERATED 1)
+
+set(
+ SRCS
+
+ src/powerd.cpp
+ src/display.c
+ src/powerd-object.c
+ src/power-request.c
+ src/powerd-sensors.cpp
+ src/${GDBUS_NAME}.c
+)
link_directories(
${GLIB_LIBRARY_DIRS}
+ ${GIO_LIBRARY_DIRS}
+ ${GIO-UNIX_LIBRARY_DIRS}
${GUDEV_LIBRARY_DIRS}
+ ${UUID_LIBRARY_DIRS}
)
include_directories(
${GLIB_INCLUDE_DIRS}
+ ${GIO_INCLUDE_DIRS}
+ ${GIO-UNIX_INCLUDE_DIRS}
${GUDEV_INCLUDE_DIRS}
+ ${UUID_INCLUDE_DIRS}
+ ${PROJECT_SOURCE_DIR}/libsuspend
+ ${CMAKE_CURRENT_BINARY_DIR}/src
)
+add_subdirectory(libsuspend)
+add_subdirectory(src)
+add_subdirectory(cli)
+
+include(UseGSettings)
+SET (POWERD_SCHEMAS "data/com.canonical.powerd.gschema.xml")
+add_schema(${POWERD_SCHEMAS})
+
add_executable(
powerd
${SRCS}
)
+add_dependencies(
+ powerd
+
+ dbus_bindings
+ ${POWERD_SCHEMAS}
+)
+
target_link_libraries(
powerd
+ suspend
is
sf
hybris_ics
${GLIB_LIBRARIES}
${GUDEV_LIBRARIES}
+ ${GIO_LIBRARIES}
+ ${GIO-UNIX_LIBRARIES}
+ ${PHABLET_LIBRARIES}
+ "-lubuntu_application_api"
+ ${UUID_LIBRARIES}
)
install(
diff -Nru powerd-0.5bzr9raring0/cli/CMakeLists.txt powerd-0.12/cli/CMakeLists.txt
--- powerd-0.5bzr9raring0/cli/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000
+++ powerd-0.12/cli/CMakeLists.txt 2013-06-03 17:17:09.000000000 +0000
@@ -0,0 +1,47 @@
+set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O0 -ggdb -g")
+
+set(
+ SRCS
+
+ powerd-cli.c
+)
+
+link_directories(
+ ${GLIB_LIBRARY_DIRS}
+ ${GIO_LIBRARY_DIRS}
+ ${GIO-UNIX_LIBRARY_DIRS}
+ ${GUDEV_LIBRARY_DIRS}
+ ${UUID_LIBRARY_DIRS}
+)
+
+include_directories(
+ ${GLIB_INCLUDE_DIRS}
+ ${GIO_INCLUDE_DIRS}
+ ${GIO-UNIX_INCLUDE_DIRS}
+ ${GUDEV_INCLUDE_DIRS}
+ ${UUID_INCLUDE_DIRS}
+ ../src
+)
+
+add_executable(
+ powerd-cli
+
+ ${SRCS}
+)
+
+target_link_libraries(
+ powerd-cli
+
+ ${GLIB_LIBRARIES}
+ ${GUDEV_LIBRARIES}
+ ${GIO_LIBRARIES}
+ ${GIO-UNIX_LIBRARIES}
+ ${UUID_LIBRARIES}
+)
+
+install(
+ TARGETS powerd-cli
+ RUNTIME DESTINATION bin
+ LIBRARY DESTINATION lib
+ ARCHIVE DESTINATION lib/static
+)
diff -Nru powerd-0.5bzr9raring0/cli/powerd-cli.c powerd-0.12/cli/powerd-cli.c
--- powerd-0.5bzr9raring0/cli/powerd-cli.c 1970-01-01 00:00:00.000000000 +0000
+++ powerd-0.12/cli/powerd-cli.c 2013-06-03 17:17:09.000000000 +0000
@@ -0,0 +1,390 @@
+/*
+ * Copyright 2013 Canonical Ltd.
+ *
+ * This file is part of powerd.
+ *
+ * powerd is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 3.
+ *
+ * powerd is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#define do_test(test) \
+ ({ \
+ gboolean result; \
+ g_message("Test: " #test); \
+ result = (test); \
+ g_message(" result: %s", result ? "PASSED" : "FAILED"); \
+ result; \
+ })
+
+#define TEST_NUM_REQUESTS 5
+
+struct PublicSysRequest {
+ const gchar *owner;
+ pid_t pid;
+ int state;
+};
+
+static GMainLoop *main_loop = NULL;
+static powerd_cookie_t main_cookie;
+static gboolean check_for_pid(pid_t pid, int count, GArray *requests);
+static void sig_handler(int signum);
+
+static void
+on_powerd_signal (GDBusProxy *proxy,
+ gchar *sender_name,
+ gchar *signal_name,
+ GVariant *parameters,
+ gpointer user_data)
+{
+ int state;
+ g_warning("we get signal from %s: %s", sender_name, signal_name);
+ if (!strcmp(signal_name,"SysPowerStateChange")) {
+ g_variant_get(parameters, "(i)", &state);
+ g_warning("State is now: %d", state);
+ }
+ else {
+ g_warning("Unknown signal from powerd");
+ }
+}
+
+static gboolean
+requestSysState(GDBusProxy *proxy, int state, pid_t pid, powerd_cookie_t *cookie)
+{
+ GVariant *ret = NULL;
+ GError *error = NULL;
+ char *cookie_ptr;
+ gboolean success = TRUE;
+
+ if (proxy == NULL) {
+ g_warning("requires a valid proxy object");
+ return FALSE;
+ }
+
+ if (cookie == NULL) {
+ g_warning("requires a valid pointer for cookie");
+ return FALSE;
+ }
+
+ ret = g_dbus_proxy_call_sync(proxy,
+ "requestSysState",
+ g_variant_new("(ii)", state, pid),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ &error);
+ if (ret == NULL) {
+ g_warning("Error when calling requestSysState: %s", error->message);
+ g_error_free(error);
+ return FALSE;
+ }
+
+ g_variant_get(ret, "(&s)", &cookie_ptr);
+ if (strlen(cookie_ptr) != sizeof(powerd_cookie_t) - 1) {
+ g_warning("Returned cookie has incorrect size");
+ success = FALSE;
+ } else {
+ strncpy(*cookie, cookie_ptr, sizeof(powerd_cookie_t));
+ g_message("Got cookie: %s", *cookie);
+ }
+
+ g_variant_unref(ret);
+ return success;
+}
+
+static GArray*
+listSysRequests(GDBusProxy *proxy)
+{
+ GVariant *ret, *item = NULL;
+ GVariantIter *iter = NULL;
+ GArray *retarray = g_array_new(FALSE, FALSE, sizeof(struct PublicSysRequest));
+ GError *error = NULL;
+ struct PublicSysRequest psr;
+
+ if (proxy == NULL) {
+ g_warning("requires a valid proxy object");
+ return retarray;
+ }
+
+ ret = g_dbus_proxy_call_sync(proxy,
+ "listSysRequests",
+ NULL,
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ &error);
+ if (ret == NULL) {
+ g_warning("Error when calling listSysRequests: %s", error->message);
+ g_error_free(error);
+ }
+ else {
+ g_variant_get(ret, "(a(sii))", &iter);
+ g_message("Current Sys Requests:");
+ while ((item = g_variant_iter_next_value (iter))) {
+ g_variant_get_child (item, 0, "s", &psr.owner);
+ g_variant_get_child (item, 1, "i", &psr.pid);
+ g_variant_get_child (item, 2, "i", &psr.state);
+ g_message(" Owner: %s, Pid: %d, State: %d", psr.owner,
+ psr.pid, psr.state);
+ g_array_append_val(retarray, psr);
+ g_variant_unref(item);
+ }
+ if (retarray->len == 0) {
+ g_message(" None");
+ }
+ g_variant_unref(ret);
+ }
+ return retarray;
+}
+
+static gboolean
+clearSysState(GDBusProxy *proxy, powerd_cookie_t cookie)
+{
+ GVariant *ret = NULL;
+ GError *error = NULL;
+
+ if (proxy == NULL) {
+ g_warning("requires a valid proxy object");
+ return FALSE;
+ }
+
+ ret = g_dbus_proxy_call_sync(proxy,
+ "clearSysState",
+ g_variant_new("(s)", cookie),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ &error);
+ if (ret == NULL) {
+ g_warning("Error when calling clearSysState: %s", error->message);
+ g_error_free(error);
+ return FALSE;
+ }
+ g_variant_unref(ret);
+ return TRUE;
+}
+
+static void
+listenForSignals(GDBusProxy *proxy, pid_t pid)
+{
+ main_loop = g_main_loop_new (NULL, FALSE);
+
+ signal(SIGINT, sig_handler);
+
+ g_signal_connect(proxy, "g-signal", G_CALLBACK (on_powerd_signal), NULL);
+
+ g_message("Waiting for events");
+ g_main_loop_run(main_loop);
+ g_main_loop_unref(main_loop);
+}
+
+static void
+runTests(GDBusProxy *proxy, pid_t pid)
+{
+ gboolean result;
+ int i;
+ powerd_cookie_t cookie, cookies[TEST_NUM_REQUESTS];
+ GArray *requests = NULL;
+
+ if (proxy == NULL) {
+ g_warning("requires a valid proxy object");
+ return;
+ }
+
+ // Hold active state request as long we're listening for signals
+ requestSysState(proxy, POWERD_SYS_STATE_ACTIVE, pid, &main_cookie);
+
+ for (i = 0; i < TEST_NUM_REQUESTS; i++)
+ do_test(requestSysState(proxy, POWERD_SYS_STATE_ACTIVE, pid, &cookies[i]) == TRUE);
+
+ // Make sure we have at least NUM_REQUESTS + 1
+ requests = listSysRequests(proxy);
+ do_test(requests->len >= TEST_NUM_REQUESTS+1);
+ do_test(check_for_pid(pid, TEST_NUM_REQUESTS+1, requests));
+ g_array_free(requests, TRUE);
+
+ for (i = 0; i < TEST_NUM_REQUESTS; i++)
+ do_test(clearSysState(proxy, cookies[i]) == TRUE);
+
+ // We should still have at least 1 request here
+ requests = listSysRequests(proxy);
+ do_test(requests->len >= 1);
+ do_test(check_for_pid(pid, 1, requests));
+ g_array_free(requests, TRUE);
+
+ // Now try and freeing the same cookies again. They should all be
+ // invalid and thus the request fails.
+ for (i = 0; i < TEST_NUM_REQUESTS; i++)
+ do_test(clearSysState(proxy, cookies[i]) == FALSE);
+
+ // Test releasing an invalid cookie format
+ do_test(clearSysState(proxy, "bad cookie") == FALSE);
+
+ // We should still have at least 1 request here
+ requests = listSysRequests(proxy);
+ do_test(requests->len >= 1);
+ do_test(check_for_pid(pid, 1, requests));
+ g_array_free(requests, TRUE);
+
+ //cannot request the suspend state, this will fail
+ do_test(requestSysState(proxy, POWERD_SYS_STATE_SUSPEND, pid, &cookie) == FALSE);
+ //invalid values
+ do_test(requestSysState(proxy, -1, pid, &cookie) == FALSE);
+ do_test(requestSysState(proxy, POWERD_NUM_POWER_STATES, pid,&cookie) == FALSE);
+ do_test(requestSysState(proxy, POWERD_NUM_POWER_STATES+1, pid,&cookie) == FALSE);
+
+ do_test(clearSysState(proxy, main_cookie) == TRUE);
+ do_test(check_for_pid(pid, 0, requests));
+}
+
+// Check that pid appears count times in a list of sys requests
+static gboolean
+check_for_pid(pid_t pid, int count, GArray *requests)
+{
+ int i;
+ int found = 0;
+ struct PublicSysRequest *psr;
+
+ if (requests == NULL) {
+ g_warning("requests is invalid");
+ return FALSE;
+ }
+
+ for (i=0; ilen; i++)
+ {
+ psr = &g_array_index(requests, struct PublicSysRequest, i);
+ if (psr->pid == pid) {
+ found++;
+ }
+ }
+
+ if (found != count) {
+ g_warning("Expected %d requests from PID, found %d", count, found);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+static void
+sig_handler(int signum)
+{
+ g_main_loop_quit(main_loop);
+}
+
+
+static void
+usage(const char *progname)
+{
+ printf("%s Options:\n",progname);
+ printf("\tlist - list outstanding requests\n");
+ printf("\tactive - request the active state, this will return a\n"\
+ "\t\tcookie which is later used to clear the request\n");
+ printf("\tclear - clear a request given a cookie\n");
+ printf("\ttest - runs tests\n");
+ printf("\tlisten - listen for signals from powerd. This runs a\n"\
+ "\t\tgmainloop and must be manually killed.\n");
+}
+
+
+int main (int argc, char **argv)
+{
+ GDBusProxy *powerd_proxy = NULL;
+ GError *error = NULL;
+ pid_t mypid;
+ uid_t myeuid;
+ powerd_cookie_t cookie;
+ GArray *requests = NULL;
+
+ if ((argc != 2) && (argc != 3)) {
+ fprintf(stderr,"Option required\n");
+ usage(argv[0]);
+ return -1;
+ }
+ if ((strcmp(argv[1],"list")) &&
+ (strcmp(argv[1],"active")) &&
+ (strcmp(argv[1],"test")) &&
+ (strcmp(argv[1],"listen")) &&
+ (strcmp(argv[1],"clear"))) {
+ fprintf(stderr,"Invalid option %s\n",argv[1]);
+ usage(argv[0]);
+ return -1;
+ }
+
+ myeuid = geteuid();
+ if (myeuid != 0) {
+ fprintf(stderr,"You must be root to run %s\n",argv[0]);
+ return -1;
+ }
+
+ powerd_proxy = g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SYSTEM,
+ G_DBUS_PROXY_FLAGS_NONE,
+ NULL,
+ "com.canonical.powerd",
+ "/com/canonical/powerd",
+ "com.canonical.powerd",
+ NULL,
+ &error);
+
+ if (error != NULL) {
+ g_error("error, could not acquire system bus proxy for powerd: %s",
+ error->message);
+ g_error_free(error);
+ return -1;
+ }
+
+ mypid = getpid();
+ g_debug("Running as pid %d\n", mypid);
+
+ if (!strcmp(argv[1],"list")) {
+ requests = listSysRequests(powerd_proxy);
+ g_array_free(requests, TRUE);
+ }
+ else if (!strcmp(argv[1],"active")) {
+ requestSysState(powerd_proxy,1,mypid,&cookie);
+ printf("State requested, cookie is %s\n", cookie);
+ }
+ else if (!strcmp(argv[1],"clear")) {
+ if (argc != 3) {
+ fprintf(stderr,"clear requires a cookie\n");
+ usage(argv[0]);
+ return -1;
+ }
+ else {
+ uuid_t uuid;
+ if (uuid_parse(argv[2], uuid)==0) {
+ clearSysState(powerd_proxy, argv[2]);
+ }
+ else {
+ fprintf(stderr,"invalid cookie, cookie should be a UUID\n");
+ usage(argv[0]);
+ }
+ }
+ }
+ else if (!strcmp(argv[1],"test")) {
+ runTests(powerd_proxy,mypid);
+ }
+ else if (!strcmp(argv[1],"listen")) {
+ listenForSignals(powerd_proxy,mypid);
+ }
+ return 0;
+}
diff -Nru powerd-0.5bzr9raring0/cmake/COPYING-CMAKE-SCRIPTS powerd-0.12/cmake/COPYING-CMAKE-SCRIPTS
--- powerd-0.5bzr9raring0/cmake/COPYING-CMAKE-SCRIPTS 1970-01-01 00:00:00.000000000 +0000
+++ powerd-0.12/cmake/COPYING-CMAKE-SCRIPTS 2013-06-03 17:17:09.000000000 +0000
@@ -0,0 +1,22 @@
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the copyright
+ notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+3. The name of the author may not be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff -Nru powerd-0.5bzr9raring0/cmake/UseGSettings.cmake powerd-0.12/cmake/UseGSettings.cmake
--- powerd-0.5bzr9raring0/cmake/UseGSettings.cmake 1970-01-01 00:00:00.000000000 +0000
+++ powerd-0.12/cmake/UseGSettings.cmake 2013-06-03 17:17:09.000000000 +0000
@@ -0,0 +1,42 @@
+# GSettings.cmake, CMake macros written for Marlin, feel free to re-use them.
+
+option (GSETTINGS_LOCALINSTALL "Install GSettings Schemas locally instead of to the GLib prefix" ${LOCAL_INSTALL})
+
+option (GSETTINGS_COMPILE "Compile GSettings Schemas after installation" ${GSETTINGS_LOCALINSTALL})
+
+if(GSETTINGS_LOCALINSTALL)
+ message(STATUS "GSettings schemas will be installed locally.")
+endif()
+
+if(GSETTINGS_COMPILE)
+ message(STATUS "GSettings schemas will be compiled.")
+endif()
+
+macro(add_schema SCHEMA_NAME)
+
+ set(PKG_CONFIG_EXECUTABLE pkg-config)
+ # Have an option to not install the schema into where GLib is
+ if (GSETTINGS_LOCALINSTALL)
+ SET (GSETTINGS_DIR "${CMAKE_INSTALL_PREFIX}/share/glib-2.0/schemas/")
+ else (GSETTINGS_LOCALINSTALL)
+ execute_process (COMMAND ${PKG_CONFIG_EXECUTABLE} glib-2.0 --variable prefix OUTPUT_VARIABLE _glib_prefix OUTPUT_STRIP_TRAILING_WHITESPACE)
+ SET (GSETTINGS_DIR "${_glib_prefix}/share/glib-2.0/schemas/")
+ endif (GSETTINGS_LOCALINSTALL)
+
+ # Run the validator and error if it fails
+ execute_process (COMMAND ${PKG_CONFIG_EXECUTABLE} gio-2.0 --variable glib_compile_schemas OUTPUT_VARIABLE _glib_comple_schemas OUTPUT_STRIP_TRAILING_WHITESPACE)
+ execute_process (COMMAND ${_glib_comple_schemas} --dry-run --schema-file=${CMAKE_CURRENT_SOURCE_DIR}/${SCHEMA_NAME} ERROR_VARIABLE _schemas_invalid OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+ if (_schemas_invalid)
+ message (SEND_ERROR "Schema validation error: ${_schemas_invalid}")
+ endif (_schemas_invalid)
+
+ # Actually install and recomple schemas
+ message (STATUS "GSettings schemas will be installed into ${GSETTINGS_DIR}")
+ install (FILES ${CMAKE_CURRENT_SOURCE_DIR}/${SCHEMA_NAME} DESTINATION ${GSETTINGS_DIR} OPTIONAL)
+
+ if (GSETTINGS_COMPILE)
+ install (CODE "message (STATUS \"Compiling GSettings schemas\")")
+ install (CODE "execute_process (COMMAND ${_glib_comple_schemas} ${GSETTINGS_DIR})")
+ endif ()
+endmacro()
diff -Nru powerd-0.5bzr9raring0/cmake/UseGdbusCodegen.cmake powerd-0.12/cmake/UseGdbusCodegen.cmake
--- powerd-0.5bzr9raring0/cmake/UseGdbusCodegen.cmake 1970-01-01 00:00:00.000000000 +0000
+++ powerd-0.12/cmake/UseGdbusCodegen.cmake 2013-06-03 17:17:09.000000000 +0000
@@ -0,0 +1,35 @@
+cmake_minimum_required(VERSION 2.6)
+if(POLICY CMP0011)
+ cmake_policy(SET CMP0011 NEW)
+endif(POLICY CMP0011)
+
+find_program(GDBUS_CODEGEN NAMES gdbus-codegen DOC "gdbus-codegen executable")
+if(NOT GDBUS_CODEGEN)
+ message(FATAL_ERROR "Excutable gdbus-codegen not found")
+endif()
+
+function(add_gdbus_codegen)
+ set(_one_value OUTFILES NAME PREFIX NAMESPACE SERVICE_XML)
+ set(_multi_value DEPENDS)
+ cmake_parse_arguments (arg "" "${_one_value}" "${_multi_value}" ${ARGN})
+
+ if(arg_PREFIX)
+ set(PREFIX --interface-prefix ${arg_PREFIX})
+ endif()
+
+ if(arg_NAMESPACE)
+ set(NAMESPACE --c-namespace ${arg_NAMESPACE})
+ endif()
+
+ add_custom_command(
+ OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${arg_NAME}.h" "${CMAKE_CURRENT_BINARY_DIR}/${arg_NAME}.c"
+ COMMAND "${GDBUS_CODEGEN}"
+ --generate-c-code "${arg_NAME}"
+ ${PREFIX}
+ ${NAMESPACE}
+ "${arg_SERVICE_XML}"
+ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+ DEPENDS ${arg_DEPENDS} "${arg_SERVICE_XML}"
+ )
+ set(${arg_OUTFILES} ${${arg_OUTFILES}} "${CMAKE_CURRENT_BINARY_DIR}/${arg_NAME}.c" PARENT_SCOPE)
+endfunction(add_gdbus_codegen)
diff -Nru powerd-0.5bzr9raring0/data/com.canonical.powerd.gschema.xml powerd-0.12/data/com.canonical.powerd.gschema.xml
--- powerd-0.5bzr9raring0/data/com.canonical.powerd.gschema.xml 1970-01-01 00:00:00.000000000 +0000
+++ powerd-0.12/data/com.canonical.powerd.gschema.xml 2013-06-03 17:17:09.000000000 +0000
@@ -0,0 +1,10 @@
+
+
+
+
+
+ 30
+ Timeout in seconds for turning off the screen if there is no user activity
+
+
+
diff -Nru powerd-0.5bzr9raring0/data/com.canonical.powerd.xml powerd-0.12/data/com.canonical.powerd.xml
--- powerd-0.5bzr9raring0/data/com.canonical.powerd.xml 1970-01-01 00:00:00.000000000 +0000
+++ powerd-0.12/data/com.canonical.powerd.xml 2013-06-03 17:17:09.000000000 +0000
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff -Nru powerd-0.5bzr9raring0/debian/changelog powerd-0.12/debian/changelog
--- powerd-0.5bzr9raring0/debian/changelog 2013-06-03 20:37:15.000000000 +0000
+++ powerd-0.12/debian/changelog 2013-06-03 20:37:15.000000000 +0000
@@ -1,8 +1,95 @@
-powerd (0.5bzr9raring0) raring; urgency=low
+powerd (0.12) saucy; urgency=low
- * Automatic build of revision 9
+ [ Seth Forshee ]
+ * Fix use of uninitialized variable in wait_for_fb_thread(). Also
+ change type of the variable to elimante warning on 64-bit builds.
+ * Remove unnecessary calls to g_type_init()
+ * Change cookies from monotonically-increasing integer to UUIDs
+ * Add test for supplying an invalidly formatted UUID to clearSysState
+ * Improve dbus error handling
- -- PS Jenkins bot Thu, 21 Mar 2013 13:45:00 +0000
+ [ Ken VanDine ]
+ * Don't listen for proximity events of prox_sensor is NULL (LP: #1186706)
+
+ -- Sergio Schvezov Mon, 03 Jun 2013 17:33:36 -0300
+
+powerd (0.11) raring; urgency=low
+
+ [ Ricardo Mendoza ]
+ * Provide initial sensors control
+ * Turn screen off when in call and proximity = NEAR.
+
+ [ Seth Forshee ]
+ * Don't hold active request during calls
+ * Reduce notification timeout from 5s to 100ms to expedite disabling of
+ the touchscreen
+
+ -- Seth Forshee Thu, 30 May 2013 16:15:42 -0500
+
+powerd (0.10) raring; urgency=low
+
+ * Move code which manages the display to its own file
+ * Eliminate sleep before turning on display by using the
+ /sys/power/wait_for_fb_* files to synchronize with the kernel when
+ required
+ * Eliminate potential for races when calling powerd_set_display_state()
+ * Fix bug where backlight would be left at 0 brightness indefinitely
+
+ -- Seth Forshee Tue, 28 May 2013 11:43:12 -0500
+
+powerd (0.9) raring; urgency=low
+
+ * Add a dconf setting that lets users set the activity timeout
+
+ -- Matthew Fischer Fri, 24 May 2013 12:51:21 -0600
+
+powerd (0.8) raring; urgency=low
+
+ [ Seth Forshee ]
+ * Move system state processing to all be done on mainloop via a state
+ machine
+ * Emit dbus signals for state changes
+ * Wait for a timeout period before completing state changes
+ * Protect access to system state requests lists using a mutex
+ * Add wake lock interfaces to libsuspend
+ * Use wake locks to block suspend while processing incoming state change
+ requests
+ * Serialize access to activity timer
+ * Fix issue where screen may turn off during user aciivity (LP: #1183865)
+ * Bug fixes and clean-up
+
+ -- Seth Forshee Fri, 24 May 2013 11:54:09 -0500
+
+powerd (0.7) raring; urgency=low
+
+ [ Matthew Fischer ]
+ * API Change: Add state to the return value for the listRequests
+ * New CLI tool, powerd-cli, which can be used for testing, debugging,
+ or to keep the system from suspending.
+ * Exit from suspend and turn screen on when receiving an incoming SMS
+ or phone call
+
+ [ Seth Forshee ]
+ * Force the initial state to screen on, not suspended, in order to
+ alleviate problems if powerd is started when the screen is off.
+ * Fix Nexus10 suspend issue
+ * Remove unnecessary newlines from glib log messages
+
+ -- Seth Forshee Thu, 23 May 2013 12:09:05 -0500
+
+powerd (0.6) raring; urgency=low
+
+ [ Michael Frey ]
+ * Automatically suspend the device when inactive
+
+ [ Matthew Fischer ]
+ * Add dbus methods for requesting system power states
+
+ [ Seth Forshee ]
+ * Add a low-level platform-neutral suspend library
+ * Modify code internally to use system power requests
+
+ -- Matthew Fischer Tue, 21 May 2013 08:45:06 -0600
powerd (0.5) quantal; urgency=low
diff -Nru powerd-0.5bzr9raring0/debian/control powerd-0.12/debian/control
--- powerd-0.5bzr9raring0/debian/control 2013-06-03 20:37:15.000000000 +0000
+++ powerd-0.12/debian/control 2013-06-03 20:37:15.000000000 +0000
@@ -8,12 +8,17 @@
libgudev-1.0-dev,
libhybris-dev,
libgles2-mesa-dev,
-Standards-Version: 3.9.3
-Vcs-Bzr: lp:phablet-powerd
+ python,
+ libplatform-api1-dev,
+ uuid-dev
+Standards-Version: 3.9.4
+Vcs-Bzr: lp:powerd
Package: powerd
-Architecture: armel armhf
+Architecture: armhf
Depends: ${misc:Depends}, ${shlibs:Depends}
-Description: Power daemon to monitor power button events.
- This daemon provides monitoring capabilities for the ubuntu phone
- and tablet.
+Description: Power daemon to monitor and control system and display power state
+ This daemon monitors and controls system and display power states for Ubuntu
+ phone and tablet. It provides a dbus interface for system services to request
+ a power state, essentially allowing services to block suspend. Additionally
+ it monitors user activity and power button presses.
diff -Nru powerd-0.5bzr9raring0/debian/install powerd-0.12/debian/install
--- powerd-0.5bzr9raring0/debian/install 1970-01-01 00:00:00.000000000 +0000
+++ powerd-0.12/debian/install 2013-06-03 20:37:15.000000000 +0000
@@ -0,0 +1 @@
+debian/powerd.conf etc/dbus-1/system.d/
diff -Nru powerd-0.5bzr9raring0/debian/powerd.conf powerd-0.12/debian/powerd.conf
--- powerd-0.5bzr9raring0/debian/powerd.conf 1970-01-01 00:00:00.000000000 +0000
+++ powerd-0.12/debian/powerd.conf 2013-06-03 20:37:15.000000000 +0000
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff -Nru powerd-0.5bzr9raring0/debian/upstart powerd-0.12/debian/upstart
--- powerd-0.5bzr9raring0/debian/upstart 2013-06-03 20:37:15.000000000 +0000
+++ powerd-0.12/debian/upstart 2013-06-03 20:37:15.000000000 +0000
@@ -24,8 +24,10 @@
export ANDROID_ROOT=/system
export EXTERNAL_STORAGE=/mnt/sdcard
export QT_PLUGIN_PATH=/opt/qt5/plugins
+# for debugging purposes, remove when closer to shipping (mfisch)
+export G_MESSAGES_DEBUG=all
+
-
exec /usr/bin/powerd
end script
diff -Nru powerd-0.5bzr9raring0/libsuspend/CMakeLists.txt powerd-0.12/libsuspend/CMakeLists.txt
--- powerd-0.5bzr9raring0/libsuspend/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000
+++ powerd-0.12/libsuspend/CMakeLists.txt 2013-06-03 17:17:09.000000000 +0000
@@ -0,0 +1,12 @@
+set(CMAKE_C_FLAGS "-Wall -Werror -Wextra")
+
+add_library(
+ suspend
+
+ libsuspend.c
+ sysfs.c
+ autosleep.c
+ earlysuspend.c
+ legacy.c
+ mocksuspend.c
+)
diff -Nru powerd-0.5bzr9raring0/libsuspend/autosleep.c powerd-0.12/libsuspend/autosleep.c
--- powerd-0.5bzr9raring0/libsuspend/autosleep.c 1970-01-01 00:00:00.000000000 +0000
+++ powerd-0.12/libsuspend/autosleep.c 2013-06-03 17:17:09.000000000 +0000
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2013 Canonical Ltd.
+ *
+ * This file is part of powerd.
+ *
+ * powerd is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 3.
+ *
+ * powerd is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+#include
+#include "common.h"
+#include "sysfs.h"
+
+static const char autosleep_path[] = "/sys/power/autosleep";
+static const char wakelock_path[] = "/sys/power/wake_lock";
+static const char wakeunlock_path[] = "/sys/power/wake_unlock";
+static const char mem_str[] = "mem";
+static const char off_str[] = "off";
+
+static int autosleep_enter(void)
+{
+ int ret = sysfs_write(autosleep_path, mem_str, ARRAY_SIZE(mem_str) - 1);
+ return ret < 0 ? ret : 0;
+}
+
+static int autosleep_exit(void)
+{
+ int ret = sysfs_write(autosleep_path, off_str, ARRAY_SIZE(off_str) - 1);
+ return ret < 0 ? ret : 0;
+}
+
+static int autosleep_acquire_wake_lock(const char *name)
+{
+ int ret = sysfs_write(wakelock_path, name, strlen(name));
+ return ret < 0 ? ret : 0;
+}
+
+static int autosleep_release_wake_lock(const char *name)
+{
+ int ret = sysfs_write(wakeunlock_path, name, strlen(name));
+ return ret < 0 ? ret : 0;
+}
+
+static const struct suspend_handler autosleep_handler = {
+ .enter = autosleep_enter,
+ .exit = autosleep_exit,
+ .acquire_wake_lock = autosleep_acquire_wake_lock,
+ .release_wake_lock = autosleep_release_wake_lock,
+};
+
+const struct suspend_handler *autosleep_detect(void)
+{
+ if (!sysfs_file_exists(autosleep_path))
+ return NULL;
+ return &autosleep_handler;
+}
diff -Nru powerd-0.5bzr9raring0/libsuspend/common.h powerd-0.12/libsuspend/common.h
--- powerd-0.5bzr9raring0/libsuspend/common.h 1970-01-01 00:00:00.000000000 +0000
+++ powerd-0.12/libsuspend/common.h 2013-06-03 17:17:09.000000000 +0000
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2013 Canonical Ltd.
+ *
+ * This file is part of powerd.
+ *
+ * powerd is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 3.
+ *
+ * powerd is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef SUSPENDIF_H
+#define SUSPENDIF_H
+
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
+
+struct suspend_handler {
+ int (*prepare)(void);
+ int (*enter)(void);
+ int (*exit)(void);
+ int (*acquire_wake_lock)(const char *);
+ int (*release_wake_lock)(const char *);
+};
+
+const struct suspend_handler *autosleep_detect(void);
+const struct suspend_handler *earlysuspend_detect(void);
+const struct suspend_handler *legacy_detect(void);
+const struct suspend_handler *mocksuspend_detect(void);
+
+#endif /* SUSPENDIF_H */
diff -Nru powerd-0.5bzr9raring0/libsuspend/earlysuspend.c powerd-0.12/libsuspend/earlysuspend.c
--- powerd-0.5bzr9raring0/libsuspend/earlysuspend.c 1970-01-01 00:00:00.000000000 +0000
+++ powerd-0.12/libsuspend/earlysuspend.c 2013-06-03 17:17:09.000000000 +0000
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2013 Canonical Ltd.
+ *
+ * This file is part of powerd.
+ *
+ * powerd is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 3.
+ *
+ * powerd is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+#include
+#include "common.h"
+#include "sysfs.h"
+
+static const char state_path[] = "/sys/power/state";
+static const char wakelock_path[] = "/sys/power/wake_lock";
+static const char wakeunlock_path[] = "/sys/power/wake_unlock";
+static const char autosleep_path[] = "/sys/power/autosleep";
+
+static const char mem_str[] = "mem";
+static const char on_str[] = "on";
+
+static int earlysuspend_enter(void)
+{
+ int ret = sysfs_write(state_path, mem_str, ARRAY_SIZE(mem_str) - 1);
+ return ret < 0 ? ret : 0;
+}
+
+static int earlysuspend_exit(void)
+{
+ int ret = sysfs_write(state_path, on_str, ARRAY_SIZE(on_str) - 1);
+ return ret < 0 ? ret : 0;
+}
+
+static int earlysuspend_acquire_wake_lock(const char *name)
+{
+ int ret = sysfs_write(wakelock_path, name, strlen(name));
+ return ret < 0 ? ret : 0;
+}
+
+static int earlysuspend_release_wake_lock(const char *name)
+{
+ int ret = sysfs_write(wakeunlock_path, name, strlen(name));
+ return ret < 0 ? ret : 0;
+}
+
+static const struct suspend_handler earlysuspend_handler = {
+ .enter = earlysuspend_enter,
+ .exit = earlysuspend_exit,
+ .acquire_wake_lock = earlysuspend_acquire_wake_lock,
+ .release_wake_lock = earlysuspend_release_wake_lock,
+};
+
+const struct suspend_handler *earlysuspend_detect(void)
+{
+ if (!sysfs_file_exists(autosleep_path) &&
+ sysfs_file_exists(wakelock_path) &&
+ sysfs_file_exists(state_path))
+ return &earlysuspend_handler;
+
+ return NULL;
+}
diff -Nru powerd-0.5bzr9raring0/libsuspend/legacy.c powerd-0.12/libsuspend/legacy.c
--- powerd-0.5bzr9raring0/libsuspend/legacy.c 1970-01-01 00:00:00.000000000 +0000
+++ powerd-0.12/libsuspend/legacy.c 2013-06-03 17:17:09.000000000 +0000
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2013 Canonical Ltd.
+ *
+ * This file is part of powerd.
+ *
+ * powerd is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 3.
+ *
+ * powerd is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+#include
+#include "common.h"
+#include "sysfs.h"
+
+static const char state_path[] = "/sys/power/state";
+static const char wakelock_path[] = "/sys/power/wake_lock";
+static const char wakeup_count_path[] = "/sys/power/wakeup_count";
+static const char mem_str[] = "mem";
+
+#define WAKEUP_COUNT_LEN 64
+
+static int wakeup_count_supported, wakeup_count_valid;
+static char wakeup_count[WAKEUP_COUNT_LEN];
+
+static int legacy_prepare(void)
+{
+ int ret;
+
+ if (wakeup_count_supported) {
+ ret = sysfs_read(wakeup_count_path, wakeup_count, WAKEUP_COUNT_LEN);
+ if (ret < 0) {
+ wakeup_count_valid = 0;
+ return ret;
+ }
+ wakeup_count_valid = 1;
+ }
+
+ return 0;
+}
+
+static int legacy_enter(void)
+{
+ int ret;
+
+ if (wakeup_count_supported && wakeup_count_valid) {
+ wakeup_count_valid = 0;
+
+ ret = sysfs_write(wakeup_count_path, wakeup_count,
+ strlen(wakeup_count));
+ if (ret < 0) {
+ /* Wakup happened since reading wakeup_count */
+ return ret;
+ }
+ }
+
+ ret = sysfs_write(state_path, mem_str, ARRAY_SIZE(mem_str) - 1);
+ return ret < 0 ? ret : 0;
+}
+
+static const struct suspend_handler legacy_handler = {
+ .prepare = legacy_prepare,
+ .enter = legacy_enter,
+};
+
+const struct suspend_handler *legacy_detect(void)
+{
+ if (sysfs_file_exists(state_path) && !sysfs_file_exists(wakelock_path)) {
+ wakeup_count_supported = sysfs_file_exists(wakeup_count_path);
+ return &legacy_handler;
+ }
+
+ return NULL;
+}
diff -Nru powerd-0.5bzr9raring0/libsuspend/libsuspend.c powerd-0.12/libsuspend/libsuspend.c
--- powerd-0.5bzr9raring0/libsuspend/libsuspend.c 1970-01-01 00:00:00.000000000 +0000
+++ powerd-0.12/libsuspend/libsuspend.c 2013-06-03 17:17:09.000000000 +0000
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2013 Canonical Ltd.
+ *
+ * This file is part of powerd.
+ *
+ * powerd is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 3.
+ *
+ * powerd is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+#include
+#include "libsuspend.h"
+#include "common.h"
+
+const struct suspend_handler *handler;
+
+void libsuspend_init(int force_mock)
+{
+ if (!force_mock) {
+ handler = autosleep_detect();
+ if (handler)
+ return;
+
+ handler = earlysuspend_detect();
+ if (handler)
+ return;
+
+ handler = legacy_detect();
+ if (handler)
+ return;
+
+ printf("No suspend interface detected, using mock suspend\n");
+ }
+
+ handler = mocksuspend_detect();
+}
+
+int libsuspend_prepare_suspend(void)
+{
+ if (!handler)
+ return -ENODEV;
+
+ if (handler->prepare)
+ return handler->prepare();
+
+ return 0;
+}
+
+int libsuspend_enter_suspend(void)
+{
+ if (!handler)
+ return -ENODEV;
+
+ if (handler->enter)
+ return handler->enter();
+
+ return 0;
+}
+
+int libsuspend_exit_suspend(void)
+{
+ if (!handler)
+ return -ENODEV;
+
+ if (handler->exit)
+ return handler->exit();
+
+ return 0;
+}
+
+int libsuspend_acquire_wake_lock(const char *name)
+{
+ if (!handler)
+ return -ENODEV;
+
+ if (handler->acquire_wake_lock)
+ return handler->acquire_wake_lock(name);
+
+ return 0;
+}
+
+int libsuspend_release_wake_lock(const char *name)
+{
+ if (!handler)
+ return -ENODEV;
+
+ if (handler->release_wake_lock)
+ return handler->release_wake_lock(name);
+
+ return 0;
+}
diff -Nru powerd-0.5bzr9raring0/libsuspend/libsuspend.h powerd-0.12/libsuspend/libsuspend.h
--- powerd-0.5bzr9raring0/libsuspend/libsuspend.h 1970-01-01 00:00:00.000000000 +0000
+++ powerd-0.12/libsuspend/libsuspend.h 2013-06-03 17:17:09.000000000 +0000
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2013 Canonical Ltd.
+ *
+ * This file is part of powerd.
+ *
+ * powerd is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 3.
+ *
+ * powerd is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef LIBSUSPEND_H
+#define LIBSUSPEND_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void libsuspend_init(int force_mock);
+int libsuspend_prepare_suspend(void);
+int libsuspend_enter_suspend(void);
+int libsuspend_exit_suspend(void);
+int libsuspend_acquire_wake_lock(const char *name);
+int libsuspend_release_wake_lock(const char *name);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LIBSUSPEND_H */
diff -Nru powerd-0.5bzr9raring0/libsuspend/mocksuspend.c powerd-0.12/libsuspend/mocksuspend.c
--- powerd-0.5bzr9raring0/libsuspend/mocksuspend.c 1970-01-01 00:00:00.000000000 +0000
+++ powerd-0.12/libsuspend/mocksuspend.c 2013-06-03 17:17:09.000000000 +0000
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2013 Canonical Ltd.
+ *
+ * This file is part of powerd.
+ *
+ * powerd is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 3.
+ *
+ * powerd is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+#include "common.h"
+
+static int mocksuspend_prepare(void)
+{
+ printf("mocksuspend prepare\n");
+ return 0;
+}
+
+static int mocksuspend_enter(void)
+{
+ printf("mocksuspend enter\n");
+ return 0;
+}
+
+static int mocksuspend_exit(void)
+{
+ printf("mocksuspend exit\n");
+ return 0;
+}
+
+static int mocksuspend_acquire_wake_lock(const char *name)
+{
+ printf("mocksuspend acquire wake lock %s\n", name);
+ return 0;
+}
+
+static int mocksuspend_release_wake_lock(const char *name)
+{
+ printf("mocksuspend release wake lock %s\n", name);
+ return 0;
+}
+
+static const struct suspend_handler mocksuspend_handler = {
+ .prepare = mocksuspend_prepare,
+ .enter = mocksuspend_enter,
+ .exit = mocksuspend_exit,
+ .acquire_wake_lock = mocksuspend_acquire_wake_lock,
+ .release_wake_lock = mocksuspend_release_wake_lock,
+};
+
+const struct suspend_handler *mocksuspend_detect(void)
+{
+ return &mocksuspend_handler;
+}
diff -Nru powerd-0.5bzr9raring0/libsuspend/sysfs.c powerd-0.12/libsuspend/sysfs.c
--- powerd-0.5bzr9raring0/libsuspend/sysfs.c 1970-01-01 00:00:00.000000000 +0000
+++ powerd-0.12/libsuspend/sysfs.c 2013-06-03 17:17:09.000000000 +0000
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2013 Canonical Ltd.
+ *
+ * This file is part of powerd.
+ *
+ * powerd is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 3.
+ *
+ * powerd is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+#include
+#include
+#include
+#include
+
+int sysfs_file_exists(const char *path)
+{
+ return !access(path, F_OK);
+}
+
+int sysfs_read(const char *path, void *buf, int len)
+{
+ int fd;
+ ssize_t ret;
+
+ fd = open(path, O_RDONLY);
+ if (fd == -1)
+ return -errno;
+
+ ret = read(fd, buf, len);
+ if (ret == -1)
+ ret = -errno;
+
+ close(fd);
+ return ret;
+}
+
+int sysfs_write(const char *path, const void *buf, int len)
+{
+ int fd;
+ ssize_t ret;
+
+ fd = open(path, O_WRONLY);
+ if (fd == -1)
+ return -errno;
+
+ ret = write(fd, buf, len);
+ if (ret == -1)
+ ret = -errno;
+
+ close(fd);
+ return ret;
+}
diff -Nru powerd-0.5bzr9raring0/libsuspend/sysfs.h powerd-0.12/libsuspend/sysfs.h
--- powerd-0.5bzr9raring0/libsuspend/sysfs.h 1970-01-01 00:00:00.000000000 +0000
+++ powerd-0.12/libsuspend/sysfs.h 2013-06-03 17:17:09.000000000 +0000
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2013 Canonical Ltd.
+ *
+ * This file is part of powerd.
+ *
+ * powerd is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 3.
+ *
+ * powerd is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef SYSFS_H
+#define SYSFS_H
+
+int sysfs_file_exists(const char *path);
+int sysfs_read(const char *path, void *buf, int len);
+int sysfs_write(const char *path, const void *buf, int len);
+
+#endif /* SYSFS_H */
diff -Nru powerd-0.5bzr9raring0/src/CMakeLists.txt powerd-0.12/src/CMakeLists.txt
--- powerd-0.5bzr9raring0/src/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000
+++ powerd-0.12/src/CMakeLists.txt 2013-06-03 17:17:09.000000000 +0000
@@ -0,0 +1,18 @@
+include(UseGdbusCodegen)
+include_directories(${CMAKE_CURRENT_BINARY_DIR})
+
+set(GDBUS_NAME powerd-dbus)
+
+set(POWERD_GENERATED_SOURCES
+ ${GDBUS_NAME}.c
+)
+set(POWERD_GENERATED_HEADERS
+ ${GDBUS_NAME}.h
+)
+
+add_gdbus_codegen(
+ OUTFILES POWERD_GENERATED_SOURCES
+ NAME ${GDBUS_NAME}
+ SERVICE_XML ${CMAKE_CURRENT_SOURCE_DIR}/../data/com.canonical.powerd.xml
+)
+ADD_CUSTOM_TARGET(dbus_bindings DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${POWERD_GENERATED_SOURCES})
diff -Nru powerd-0.5bzr9raring0/src/display.c powerd-0.12/src/display.c
--- powerd-0.5bzr9raring0/src/display.c 1970-01-01 00:00:00.000000000 +0000
+++ powerd-0.12/src/display.c 2013-06-03 17:17:09.000000000 +0000
@@ -0,0 +1,274 @@
+/*
+ * Copyright 2013 Canonical Ltd.
+ *
+ * Authors:
+ * Michael Frey: michael.frey@canonical.com
+ * Matthew Fischer: matthew.fischer@canonical.com
+ * Seth Forshee: seth.forshee@canonical.com
+ *
+ * This file is part of powerd.
+ *
+ * powerd is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 3.
+ *
+ * powerd is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+
+#include "powerd.h"
+#include "powerd-internal.h"
+
+static gint saved_brightness = 255;
+static gchar *brightness_path;
+
+/* Assume screen is off to start; we will force it on */
+static enum powerd_display_state current_display_state = POWERD_DISPLAY_OFF;
+static GMutex display_state_mutex;
+static uuid_t internal_request_cookie;
+
+enum fb_state {
+ FB_SLEEP,
+ FB_AWAKE,
+
+ NUM_FB_STATES
+};
+static enum fb_state fb_state = FB_AWAKE;
+
+static const char *fb_file_names[] = {
+ [FB_SLEEP] = "/sys/power/wait_for_fb_sleep",
+ [FB_AWAKE] = "/sys/power/wait_for_fb_wake"
+};
+
+static void get_brightness_path(void)
+{
+ GUdevClient *client;
+ GList *devices;
+ GList *device;
+ const gchar *device_type;
+
+ // detect device
+ client = g_udev_client_new(NULL);
+ devices = g_udev_client_query_by_subsystem(client, "backlight");
+ if (devices == NULL) {
+ g_warning("Fail to query backlight devices.");
+ g_object_unref(client);
+ return;
+ }
+
+ for (device = devices; device != NULL; device = device->next) {
+ device_type = g_udev_device_get_sysfs_attr((GUdevDevice *)device->data, "type");
+ if ((g_strcmp0(device_type, "firmware") == 0) ||
+ (g_strcmp0(device_type, "platform") == 0) ||
+ (g_strcmp0(device_type, "raw") == 0)) {
+ brightness_path = g_strdup(g_udev_device_get_sysfs_path((GUdevDevice *)device->data));
+ break;
+ }
+ }
+
+ g_list_foreach(devices, (GFunc) g_object_unref, NULL);
+ g_list_free(devices);
+
+ g_object_unref(client);
+}
+
+
+void powerd_brightness_set_value(gint value)
+{
+ gint fd;
+ gchar *filename;
+ gchar *svalue;
+ gint length;
+
+ filename = g_build_filename(brightness_path, "brightness", NULL);
+ fd = open(filename, O_WRONLY);
+ if (fd < 0) {
+ g_warning("Fail to set brightness.");
+ g_free(filename);
+ return;
+ }
+
+ svalue = g_strdup_printf("%i", value);
+ length = strlen(svalue);
+
+ if (write(fd, svalue, length) != length) {
+ g_warning("Fail to write brightness information.");
+ }
+
+ close(fd);
+ g_free(svalue);
+ g_free(filename);
+}
+
+static gint brightness_get_value(void)
+{
+ GError *error;
+ gchar *svalue;
+ gint value;
+ gchar *filename;
+
+ svalue = NULL;
+ error = NULL;
+ filename = g_build_filename(brightness_path, "brightness", NULL);
+ g_file_get_contents(filename, &svalue, NULL, &error);
+ if (error) {
+ g_warning("Fail to get brightness value: %s", error->message);
+ value = -1;
+ g_error_free(error);
+ } else {
+ value = atoi(svalue);
+ }
+
+ g_free(filename);
+
+ return value;
+
+}
+
+static void turn_on_display(void) {
+ g_debug("turning on display");
+ sf_unblank(0);
+ powerd_brightness_set_value(saved_brightness);
+}
+
+enum powerd_display_state powerd_get_display_state(void)
+{
+ return current_display_state;
+}
+
+int powerd_set_display_state(enum powerd_display_state new_state)
+{
+ int ret, ret_code = 0;
+ int brightness;
+
+ g_debug("powerd_set_display_state: current %s (%d) new %s (%d)",
+ state_to_string(current_display_state), current_display_state,
+ state_to_string(new_state), new_state);
+
+ if (current_display_state == new_state)
+ return 0;
+
+ g_mutex_lock(&display_state_mutex);
+
+ switch (new_state) {
+ case POWERD_DISPLAY_OFF:
+ g_debug("turning off display");
+ powerd_reset_activity_timer(0);
+ brightness = brightness_get_value();
+ saved_brightness = (brightness != 0) ? brightness : saved_brightness;
+ powerd_brightness_set_value(0);
+ sf_blank(0);
+
+ g_debug("Releasing internal active state request");
+ ret = clear_sys_state_internal(internal_request_cookie);
+ if (!ret) {
+ char cookie_str[UUID_STR_LEN];
+ uuid_unparse(internal_request_cookie, cookie_str);
+ g_warning("Internal system state request cookie invalid: %s",
+ cookie_str);
+ }
+ break;
+ case POWERD_DISPLAY_ON:
+ g_debug("Requesting active state internally");
+ ret = request_sys_state_internal(POWERD_SYS_STATE_ACTIVE, getpid(),
+ &internal_request_cookie, NULL);
+ if (!ret)
+ g_warning("Request for active state failed");
+
+ /*
+ * If the current state is suspend we need to wait for
+ * notification of leaving the active state, otherwise the
+ * screen may fail to turn on for devices using earlysuspend.
+ * Otherwise we can turn on the screen right away.
+ */
+ if (fb_state == FB_AWAKE)
+ turn_on_display();
+
+ powerd_reset_activity_timer(1);
+ break;
+ default:
+ g_warning("Invalid display state %d", new_state);
+ ret_code = -1;
+ goto unlock;
+ }
+
+ current_display_state = new_state;
+unlock:
+ g_mutex_unlock(&display_state_mutex);
+ return ret_code;
+}
+
+static int wait_for_file(const char *fname)
+{
+ int fd, ret;
+ char buf;
+
+ fd = open(fname, O_RDONLY);
+ if (fd == -1)
+ return -errno;
+
+ do {
+ ret = read(fd, &buf, 1);
+ } while (ret == -1 && errno == EINTR);
+
+ close(fd);
+ return ret == -1 ? -errno : 0;
+}
+
+static gboolean fb_state_changed(gpointer data)
+{
+ fb_state = (enum fb_state)data;
+ g_debug("fb state %s", fb_state == FB_SLEEP ? "sleep" : "awake");
+ if (fb_state == FB_AWAKE && current_display_state == POWERD_DISPLAY_ON)
+ turn_on_display();
+}
+
+static gpointer wait_for_fb_thread(gpointer unused)
+{
+ unsigned long state = fb_state;
+
+ if (state >= NUM_FB_STATES) {
+ g_warning("Invalid FB state");
+ return NULL;
+ }
+
+ while (1) {
+ state = (state == FB_SLEEP) ? FB_AWAKE : FB_SLEEP;
+ if (wait_for_file(fb_file_names[state])) {
+ g_warning("Error reading %s", fb_file_names[state]);
+ return NULL;
+ }
+ g_timeout_add(0, fb_state_changed, (gpointer)state);
+ }
+ return NULL;
+}
+
+int powerd_display_init(void)
+{
+ GError *error;
+
+ get_brightness_path();
+
+ /* If kernel supports earlysuspend, start thread to monitor fb state */
+ if (!access(fb_file_names[FB_SLEEP], F_OK))
+ g_thread_new("powerd_fb_wake_monitor", wait_for_fb_thread, &error);
+
+ return 0;
+}
diff -Nru powerd-0.5bzr9raring0/src/power-request.c powerd-0.12/src/power-request.c
--- powerd-0.5bzr9raring0/src/power-request.c 1970-01-01 00:00:00.000000000 +0000
+++ powerd-0.12/src/power-request.c 2013-06-03 17:17:09.000000000 +0000
@@ -0,0 +1,648 @@
+/*
+ * Copyright 2013 Canonical Ltd.
+ *
+ * This file is part of powerd.
+ *
+ * powerd is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 3.
+ *
+ * powerd is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include "powerd-internal.h"
+#include "powerd-dbus.h"
+
+#include "libsuspend.h"
+
+#define NOTIFICATION_TIMEOUT_MSECS 100
+
+struct SysStateRequest {
+ gchar *owner;
+ uuid_t cookie;
+ int pid;
+ enum SysPowerStates state;
+};
+
+/*
+ * Current system power state. Assume we are suspended to start. We will
+ * be forced into the active state during initialization, and this
+ * ensures that the system state is consistent with our internal state.
+ */
+static enum SysPowerStates current_system_state = POWERD_SYS_STATE_SUSPEND;
+
+/*
+ * Lists for system power state requests, with one list for each power
+ * level. Requests for the suspend state are not allowed, so the actual
+ * number of lists is POWERD_NUM_POWER_STATES - 1. Access to this list
+ * is protected by state_request_mutex.
+ */
+static GSList *sys_state_requests[POWERD_NUM_POWER_STATES - 1];
+
+/* Mutex to protect code accessing sys_state_requests */
+static GMutex state_request_mutex;
+
+/*
+ * States for "state transition" state machine.
+ *
+ * When no state transition is in progress we're in the idle state. When
+ * a state transition is initiated we proceed through the other states
+ * in order. When finished, we start at the begining if another state
+ * transition is pending or return to idle otherwise.
+ */
+enum state_transition_state {
+ STATE_TRANSITION_IDLE, /* No transition in progress */
+ STATE_TRANSITION_DEQUEUE, /* Dequeueing next state transition */
+ STATE_TRANSITION_NOTIFY, /* Notifying clients / waiting for acks */
+ STATE_TRANSITION_COMPLETE, /* Completing the state transition */
+
+ NUM_STATE_TRANSITIONS
+};
+
+static enum state_transition_state cur_state_transition_state = STATE_TRANSITION_IDLE;
+
+#define INVALID_STATE -1
+static GQueue queued_state_changes;
+static enum SysPowerStates pending_system_state = INVALID_STATE;
+static gint update_pending;
+
+static const char power_request_wakelock_name[] = "powerd_power_request";
+gint suspend_block_count;
+
+static void state_transition_process(void);
+
+enum SysPowerStates current_system_power_state(void)
+{
+ return current_system_state;
+}
+
+/* simple helper for debugging */
+const gchar *
+state_to_string(int state)
+{
+ switch (state) {
+ case POWERD_SYS_STATE_ACTIVE: return "ACTIVE";
+ case POWERD_SYS_STATE_SUSPEND: return "SUSPEND";
+ default: return "UNKNOWN";
+ }
+}
+
+/*
+ * block_suspend and unblock_suspend are only for use when new requests
+ * are received, to ensure that autosuspend doesn't suspend the system
+ * before the main loop can disable it after an active state request
+ * is received.
+ */
+static void block_suspend(void)
+{
+ int ret;
+
+ if (g_atomic_int_add(&suspend_block_count, 1) == 0) {
+ int test;
+ g_debug("Blocking suspend");
+ ret = libsuspend_acquire_wake_lock(power_request_wakelock_name);
+ if (ret)
+ g_warning("Could not acquire wake lock");
+ }
+}
+
+static void unblock_suspend(void)
+{
+ gint old_count;
+ int ret;
+ gboolean retry;
+
+ do {
+ old_count = g_atomic_int_get(&suspend_block_count);
+ if (old_count == 0) {
+ g_warning("Suspend not blocked, refusing to unblock");
+ return;
+ }
+ retry = !g_atomic_int_compare_and_exchange(&suspend_block_count,
+ old_count, old_count - 1);
+ if (!retry && old_count == 1) {
+ g_debug("Unblocking suspend");
+ ret = libsuspend_release_wake_lock(power_request_wakelock_name);
+ if (ret)
+ g_warning("Could not release wake lock");
+ }
+ } while (retry);
+}
+
+/* Returns TRUE if the state request is valid, FALSE otherwise.
+ * Nobody can request the SUSPEND state. */
+static gboolean
+is_valid_state_request(int state)
+{
+ return state > POWERD_SYS_STATE_SUSPEND && state < POWERD_NUM_POWER_STATES;
+}
+
+/* Callers must hold state_request_mutex */
+static GSList **
+sys_request_list(int state)
+{
+ if (!is_valid_state_request(state))
+ return NULL;
+ return &sys_state_requests[state - 1];
+}
+
+/* internal callers should pass in NULL for the builder, its only used
+ * by dbus callers. Returns TRUE if there are any elements in any list,
+ * FALSE otherwise. */
+static gint
+list_sys_requests_internal(GVariantBuilder *builder)
+{
+ gint count = 0;
+ GSList **list, *iterator = NULL;
+ int i;
+
+ g_mutex_lock(&state_request_mutex);
+
+ for (i = POWERD_SYS_STATE_SUSPEND + 1; i < POWERD_NUM_POWER_STATES; i++) {
+ list = sys_request_list(i);
+
+ g_message("Requests for %s state:", state_to_string(i));
+ if (*list == NULL) {
+ g_message(" no requests active");
+ }
+ else {
+ for (iterator = *list; iterator; iterator = iterator->next) {
+ struct SysStateRequest *sr = (struct SysStateRequest *)iterator->data;
+ char cookie_str[UUID_STR_LEN];
+
+ /* XXX: For debug, remove later */
+ uuid_unparse(sr->cookie, cookie_str);
+ g_message(" Owner: %s, Pid: %d, Cookie: %s, State: %s (%d)",
+ sr->owner, sr->pid, cookie_str,
+ state_to_string(sr->state), sr->state);
+
+ if (builder) {
+ g_variant_builder_add(builder, "(sii)", sr->owner,
+ sr->pid, sr->state);
+ count++;
+ }
+ }
+ }
+ }
+
+ g_mutex_unlock(&state_request_mutex);
+ return count;
+}
+
+/* Dump the requests to stdout and return the list via dbus */
+gboolean
+handle_list_sys_requests(PowerdSource *obj, GDBusMethodInvocation *invocation)
+{
+ GVariant *list, *tuple = NULL;
+ GVariantBuilder *builder;
+ gint count = 0;
+
+ builder = g_variant_builder_new(G_VARIANT_TYPE("a(sii)"));
+ count = list_sys_requests_internal(builder);
+ if (count>0) {
+ list = g_variant_builder_end(builder);
+ }
+ else {
+ g_variant_builder_clear(builder);
+ list = g_variant_new_array(G_VARIANT_TYPE("(sii)"), NULL, 0);
+ }
+ tuple = g_variant_new_tuple(&list,1);
+ g_dbus_method_invocation_return_value(invocation, tuple);
+ g_variant_builder_unref(builder);
+ return TRUE;
+}
+
+static gint
+find_request_by_cookie(gconstpointer a, gconstpointer b)
+{
+ struct SysStateRequest *sr_a = (struct SysStateRequest *)a;
+ struct SysStateRequest *sr_b = (struct SysStateRequest *)b;
+ return memcmp(sr_a->cookie, sr_b->cookie, sizeof(sr_a->cookie));
+}
+
+/* Note: owner is NULL for internal usage */
+gboolean
+request_sys_state_internal(int state, int pid, uuid_t *cookie, const gchar *owner)
+{
+ GSList **list, *item = NULL;
+ struct SysStateRequest *sr = NULL;
+ uuid_t uuid;
+
+ if (cookie == NULL) {
+ g_error("you need to pass in memory for a cookie");
+ return FALSE;
+ }
+
+ if (!is_valid_state_request(state))
+ {
+ g_warning("invalid state requested: %d",state);
+ return FALSE;
+ }
+
+ g_mutex_lock(&state_request_mutex);
+
+ list = sys_request_list(state);
+ if (!list) {
+ /* Should never hit this code since we've already verified that
+ * the state is valid */
+ g_error("Could not get request list for state %d (%s)", state,
+ state_to_string(state));
+ g_mutex_unlock(&state_request_mutex);
+ return FALSE;
+ }
+
+ sr = g_new(struct SysStateRequest, 1);
+ sr->state = (enum SysPowerStates)state;
+ sr->pid = pid;
+ if (owner) {
+ sr->owner = g_strdup(owner);
+ }
+ else {
+ sr->owner = g_strdup("internal");
+ }
+
+ // The request is valid at this point, create a cookie and insert into list
+ uuid_generate(sr->cookie);
+ memcpy(*cookie, sr->cookie, sizeof(sr->cookie));
+ *list = g_slist_append(*list, sr);
+ g_mutex_unlock(&state_request_mutex);
+
+ update_system_state();
+ return TRUE;
+}
+
+gboolean
+handle_request_sys_state (PowerdSource *obj, GDBusMethodInvocation *invocation, int state, int pid)
+{
+ gboolean retval;
+ const char *owner;
+ uuid_t cookie;
+ char ext_cookie[UUID_STR_LEN];
+
+ owner = g_dbus_method_invocation_get_sender(invocation);
+ g_debug("handle_requestSysState from %s: %d - %s (%d)", owner, pid,
+ state_to_string(state), state);
+
+ retval = request_sys_state_internal(state, pid, &cookie, owner);
+ if (retval == TRUE) {
+ g_debug("handle_requestSysState - SUCCESS");
+ uuid_unparse(cookie, ext_cookie);
+ g_dbus_method_invocation_return_value(invocation,
+ g_variant_new("(s)", ext_cookie));
+ } else {
+ g_dbus_method_invocation_return_error(invocation, G_DBUS_ERROR,
+ G_DBUS_ERROR_INVALID_ARGS, "Invalid state request");
+ }
+ return TRUE;
+}
+
+gboolean
+clear_sys_state_internal(uuid_t cookie)
+{
+ struct SysStateRequest *tmpsr = NULL;
+ GSList **list, *matched_requests = NULL;
+ int i;
+ char cookie_str[UUID_STR_LEN];
+
+ tmpsr = g_new(struct SysStateRequest, 1);
+ memcpy(tmpsr->cookie, cookie, sizeof(tmpsr->cookie));
+
+ g_mutex_lock(&state_request_mutex);
+ for (i = POWERD_SYS_STATE_SUSPEND + 1; i < POWERD_NUM_POWER_STATES; i++) {
+ list = sys_request_list(i);
+ if (!list)
+ continue;
+
+ matched_requests = g_slist_find_custom(*list, tmpsr, find_request_by_cookie);
+
+ if (matched_requests)
+ break;
+ }
+ g_free(tmpsr);
+
+ if (matched_requests == NULL)
+ {
+ uuid_unparse(tmpsr->cookie, cookie_str);
+ g_warning("request (%s) not found", cookie_str);
+ g_mutex_unlock(&state_request_mutex);
+ return FALSE;
+ }
+
+ for ( ; matched_requests; matched_requests = matched_requests->next) {
+ struct SysStateRequest *sr = (struct SysStateRequest *)matched_requests->data;
+
+ /* XXX: Remove later to avoid unconditional unparse */
+ uuid_unparse(sr->cookie, cookie_str);
+ g_debug("removing an element: %s", cookie_str);
+
+ *list = g_slist_remove_all(*list, sr);
+ }
+ g_mutex_unlock(&state_request_mutex);
+
+ g_slist_free_full(matched_requests, sys_state_request_destroy);
+ update_system_state();
+ return TRUE;
+}
+
+gboolean
+handle_clear_sys_state(PowerdSource *obj, GDBusMethodInvocation *invocation,
+ gchar *ext_cookie)
+{
+ gboolean retval;
+ uuid_t cookie;
+
+ g_debug("handle_clearSysState from %s, cookie: %s",
+ g_dbus_method_invocation_get_sender(invocation), ext_cookie);
+
+ if (uuid_parse(ext_cookie, cookie)) {
+ g_dbus_method_invocation_return_error(invocation, G_DBUS_ERROR,
+ G_DBUS_ERROR_INVALID_ARGS,
+ "Invalid cookie: %s", ext_cookie);
+ return TRUE;
+ }
+
+ retval = clear_sys_state_internal(cookie);
+ if (retval == TRUE) {
+ g_dbus_method_invocation_return_value(invocation, NULL);
+ } else {
+ g_dbus_method_invocation_return_error(invocation, G_DBUS_ERROR,
+ G_DBUS_ERROR_INVALID_ARGS,
+ "Invalid cookie: %s", ext_cookie);
+ }
+ return TRUE;
+}
+
+static enum SysPowerStates max_requested_state(void)
+{
+ enum SysPowerStates ret = POWERD_SYS_STATE_SUSPEND;
+ int i;
+ GSList **list;
+
+ g_mutex_lock(&state_request_mutex);
+ for (i = POWERD_NUM_POWER_STATES - 1; i > POWERD_SYS_STATE_SUSPEND; i--) {
+ list = sys_request_list(i);
+ if (list && *list) {
+ ret = i;
+ break;
+ }
+ };
+ g_mutex_unlock(&state_request_mutex);
+
+ return ret;
+}
+
+static gboolean delayed_state_transition_process(gpointer unused)
+{
+ state_transition_process();
+ return FALSE;
+}
+
+static enum state_transition_state process_state_dequeue(guint *delay)
+{
+ int ret;
+
+ *delay = 0;
+
+ pending_system_state = (enum SysPowerStates)g_queue_pop_head(&queued_state_changes);
+ if (pending_system_state == current_system_state) {
+ g_debug("pending state == current state, discarding");
+ pending_system_state = INVALID_STATE;
+ return STATE_TRANSITION_IDLE;
+ }
+
+ if (current_system_state == POWERD_SYS_STATE_SUSPEND) {
+ g_debug("exiting suspend");
+ ret = libsuspend_exit_suspend();
+ if (ret)
+ g_warning("Failed to exit suspend: %d", ret);
+ }
+
+ /*
+ * XXX: If going to suspend we may want to delay a few seconds here
+ * in case the user immediately tries to wake the device again after
+ * an activity timeout.
+ */
+
+ /* Must call libsuspend_prepare_suspend() _before_ emitting signal */
+ if (pending_system_state == POWERD_SYS_STATE_SUSPEND) {
+ g_debug("preparing for suspend");
+ ret = libsuspend_prepare_suspend();
+ if (ret)
+ g_warning("Failed to prepare for suspend: %d", ret);
+ }
+ powerd_sys_state_signal_emit(pending_system_state);
+
+ *delay = NOTIFICATION_TIMEOUT_MSECS;
+ return STATE_TRANSITION_NOTIFY;
+}
+
+static enum state_transition_state process_state_notify(guint *delay)
+{
+ *delay = 0;
+ return STATE_TRANSITION_COMPLETE;
+}
+
+static enum state_transition_state process_state_complete(guint *delay)
+{
+ int ret;
+ gboolean allow_suspend;
+
+ *delay = 0;
+
+ /*
+ * If more requests are in the queue or new requests are present
+ * above our current target state, do not suspend so that those
+ * requests can be processed.
+ */
+ allow_suspend = !(!g_queue_is_empty(&queued_state_changes) ||
+ max_requested_state() > pending_system_state);
+
+ if (pending_system_state == POWERD_SYS_STATE_SUSPEND && allow_suspend) {
+ g_debug("entering suspend");
+ ret = libsuspend_enter_suspend();
+ if (ret)
+ g_warning("Failed to enter suspend: %d", ret);
+ }
+
+ g_debug("Transition to %s complete", state_to_string(pending_system_state));
+ current_system_state = pending_system_state;
+ pending_system_state = INVALID_STATE;
+
+ /*
+ * If state changes are queued, go back to the dequeue state. If
+ * nothing is queued and max_requested_state() > pending_system_state
+ * there should be another run of update_system_state() scheduled to
+ * take care of this.
+ */
+ return g_queue_is_empty(&queued_state_changes) ?
+ STATE_TRANSITION_IDLE : STATE_TRANSITION_DEQUEUE;
+}
+
+static void state_transition_process(void)
+{
+ guint delay;
+
+ do {
+ switch (cur_state_transition_state) {
+ case STATE_TRANSITION_DEQUEUE:
+ cur_state_transition_state = process_state_dequeue(&delay);
+ break;
+ case STATE_TRANSITION_NOTIFY:
+ cur_state_transition_state = process_state_notify(&delay);
+ break;
+ case STATE_TRANSITION_COMPLETE:
+ cur_state_transition_state = process_state_complete(&delay);
+ break;
+ }
+ } while (delay == 0 &&
+ cur_state_transition_state != STATE_TRANSITION_IDLE);
+
+ if (delay != 0 && cur_state_transition_state != STATE_TRANSITION_IDLE)
+ g_timeout_add(delay, delayed_state_transition_process, NULL);
+
+}
+
+static void check_queued_state_changes(void)
+{
+ int ret;
+
+ /*
+ * If state change in progress we'll process the next queued state
+ * change when finished.
+ */
+ if (cur_state_transition_state != STATE_TRANSITION_IDLE) {
+ g_debug("state change in progress, delaying");
+ return;
+ }
+
+ if (g_queue_is_empty(&queued_state_changes)) {
+ g_debug("no pending state changes");
+ return;
+ }
+
+ /* Start processing state transition */
+ cur_state_transition_state = STATE_TRANSITION_DEQUEUE;
+ state_transition_process();
+}
+
+
+/*
+ * XXX: Currently the coalescing is very simplistic and may need
+ * improvement.
+ */
+static void enqueue_state_change(enum SysPowerStates state)
+{
+ gboolean queue_empty;
+
+ g_debug("Enqueue state change to %s", state_to_string(state));
+
+ /*
+ * If the new request is the same as the one we're currently
+ * processing we can drop all pending requests (including the
+ * new one).
+ */
+ if (pending_system_state == state) {
+ g_debug("State == pending state, discarding");
+ g_queue_clear(&queued_state_changes);
+ return;
+ } else if (pending_system_state == INVALID_STATE) {
+ queue_empty = g_queue_is_empty(&queued_state_changes);
+
+ /*
+ * If no state changes are pending or in progress and the
+ * requested state is the same as the current state, do nothing.
+ */
+ if (queue_empty && state == current_system_state) {
+ g_debug("queue empty && state == current, discarding");
+ return;
+ }
+
+ /*
+ * If we aren't processing a request and the current request is
+ * the same as the next reques in the queue, all intermediate
+ * requests can be dropped. We do this by clearing the queue and
+ * then adding in the new request.
+ *
+ * XXX: This situation is probably impossible currently.
+ */
+ if (!queue_empty &&
+ (enum SysPowerStates)g_queue_peek_tail(&queued_state_changes) == state) {
+ g_debug("new state == next queued state, discarding all intermediate requests");
+ g_queue_clear(&queued_state_changes);
+ }
+ }
+
+ g_queue_push_tail(&queued_state_changes, (gpointer)state);
+ check_queued_state_changes();
+}
+
+static gboolean update_system_state_handler(gpointer unused)
+{
+ /*
+ * We must clear update_pending just before calling max_requested_state()
+ * to avoid races with adding new requests. We may end up with an
+ * occassional redundant system state update, but that is harmless.
+ */
+ g_atomic_int_set(&update_pending, 0);
+ enqueue_state_change(max_requested_state());
+
+ /*
+ * We assume that after enqueue_state_change() completes autosuspend
+ * will have been disabled if any active requests are present. This
+ * is currently true, but if the assumption is ever broken it will
+ * expose us to potential races.
+ */
+ unblock_suspend();
+ return FALSE;
+}
+
+void update_system_state(void)
+{
+ if (g_atomic_int_compare_and_exchange(&update_pending, 0, 1)) {
+ block_suspend();
+ g_timeout_add(0, update_system_state_handler, NULL);
+ }
+}
+
+void power_request_init(void)
+{
+ g_queue_init(&queued_state_changes);
+}
+
+// Destructor for the state request object
+void sys_state_request_destroy(gpointer data)
+{
+ struct SysStateRequest *sr = (struct SysStateRequest *)data;
+ if (sr->owner) {
+ g_free(sr->owner);
+ sr->owner = NULL;
+ }
+}
+
+void power_request_deinit(void)
+{
+ int i;
+ for (i = POWERD_SYS_STATE_SUSPEND + 1; i < POWERD_NUM_POWER_STATES; i++)
+ g_slist_free_full(sys_state_requests[i-1], sys_state_request_destroy);
+ g_queue_clear(&queued_state_changes);
+}
diff -Nru powerd-0.5bzr9raring0/src/powerd-internal.h powerd-0.12/src/powerd-internal.h
--- powerd-0.5bzr9raring0/src/powerd-internal.h 1970-01-01 00:00:00.000000000 +0000
+++ powerd-0.12/src/powerd-internal.h 2013-06-03 17:17:09.000000000 +0000
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2013 Canonical Ltd.
+ *
+ * This file is part of powerd.
+ *
+ * powerd is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 3.
+ *
+ * powerd is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef __POWERD_INTERNAL_H__
+#define __POWERD_INTERNAL_H__
+
+#include
+#include
+#include
+
+#include "powerd-object.h"
+#include "powerd.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Length of a UUID string, including trailing nul */
+#define UUID_STR_LEN 37
+
+enum powerd_display_state {
+ POWERD_DISPLAY_OFF,
+ POWERD_DISPLAY_ON
+};
+
+void powerd_exit(void);
+void powerd_reset_activity_timer(int add);
+void powerd_dbus_init_complete(void);
+
+/* Display functions */
+void powerd_brightness_set_value(gint value);
+enum powerd_display_state powerd_get_display_state(void);
+int powerd_set_display_state(enum powerd_display_state new_state);
+int powerd_display_init(void);
+
+/* System power state requests */
+gboolean handle_list_sys_requests(PowerdSource *obj,
+ GDBusMethodInvocation *invocation);
+gboolean handle_request_sys_state(PowerdSource *obj,
+ GDBusMethodInvocation *invocation,
+ int state, int pid);
+gboolean handle_clear_sys_state(PowerdSource *obj,
+ GDBusMethodInvocation *invocation,
+ gchar *cookie);
+gboolean request_sys_state_internal(int state, int pid,
+ uuid_t *cookie, const gchar *owner);
+gboolean clear_sys_state_internal(uuid_t cookie);
+void update_system_state(void);
+void power_request_init(void);
+void power_request_deinit(void);
+enum SysPowerStates current_system_power_state(void);
+void sys_state_request_destroy(gpointer data);
+const gchar * state_to_string(int state);
+void powerd_sys_state_signal_emit(enum SysPowerStates state);
+
+/* dbus callbacks */
+void powerd_bus_acquired_cb(GDBusConnection *connection, const gchar *name,
+ gpointer user_data);
+void powerd_name_acquired_cb(GDBusConnection *connection, const gchar *name,
+ gpointer user_data);
+void powerd_name_lost_cb(GDBusConnection *connection, const gchar *name,
+ gpointer user_data);
+
+/* dbus signal handlers */
+void on_ofono_signal(GDBusProxy *proxy, gchar *sender_name, gchar *signal_name,
+ GVariant *parameters, gpointer user_data);
+
+/* dbus proxy async setup */
+void ofono_proxy_connect_cb(GObject *source_object, GAsyncResult *res,
+ gpointer user_data);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff -Nru powerd-0.5bzr9raring0/src/powerd-object.c powerd-0.12/src/powerd-object.c
--- powerd-0.5bzr9raring0/src/powerd-object.c 1970-01-01 00:00:00.000000000 +0000
+++ powerd-0.12/src/powerd-object.c 2013-06-03 17:17:09.000000000 +0000
@@ -0,0 +1,174 @@
+/*
+ * Copyright 2013 Canonical Ltd.
+ *
+ * This file is part of powerd.
+ *
+ * powerd is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 3.
+ *
+ * powerd is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+#include
+#include
+#include "powerd-internal.h"
+#include "powerd-dbus.h"
+
+struct _PowerdSourcePrivate {
+ GDBusConnection * system_bus;
+ const gchar * path;
+ ComCanonicalPowerd * skel;
+};
+
+static void powerd_source_class_init (PowerdSourceClass * klass);
+static void powerd_source_init (PowerdSource * self);
+static void powerd_source_dispose (GObject * object);
+static void powerd_source_finalize (GObject * object);
+
+G_DEFINE_TYPE (PowerdSource, powerd_source, G_TYPE_OBJECT);
+
+#define POWERD_SOURCE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), POWERD_TYPE_SOURCE, PowerdSourcePrivate))
+
+/* File-local reference to the singleton object */
+static PowerdSource *powerd_source = NULL;
+
+/* Instance */
+static void
+powerd_source_init (PowerdSource *self)
+{
+ self->priv = POWERD_SOURCE_GET_PRIVATE(self);
+ self->priv->system_bus = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL);
+ return;
+}
+
+/* Class Init */
+static void
+powerd_source_class_init (PowerdSourceClass *self)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (self);
+ g_type_class_add_private (self, sizeof (PowerdSourcePrivate));
+ object_class->dispose = powerd_source_dispose;
+ object_class->finalize = powerd_source_finalize;
+ return;
+}
+
+/* Clean up references */
+static void
+powerd_source_dispose (GObject *object)
+{
+ PowerdSource * self = POWERD_SOURCE(object);
+ if (self->priv->skel != NULL) {
+ g_dbus_interface_skeleton_unexport(G_DBUS_INTERFACE_SKELETON(self->priv->skel));
+ g_clear_object(&self->priv->skel);
+ }
+ g_clear_object(&self->priv->system_bus);
+ return;
+}
+
+/* Free memory */
+static void
+powerd_source_finalize (GObject *object)
+{
+ return;
+}
+
+void
+powerd_bus_acquired_cb (GDBusConnection *connection,
+ const gchar *name,
+ gpointer user_data)
+{
+ GError *error = NULL;
+
+ g_debug("Bus acquired (guid %s)", g_dbus_connection_get_guid (connection));
+ powerd_source = (PowerdSource *)g_object_new(POWERD_TYPE_SOURCE, NULL);
+ powerd_source->priv->skel = com_canonical_powerd_skeleton_new();
+ powerd_source->priv->path = "/com/canonical/powerd";
+
+ if (!g_dbus_interface_skeleton_export(G_DBUS_INTERFACE_SKELETON(powerd_source->priv->skel),
+ powerd_source->priv->system_bus, powerd_source->priv->path, &error)) {
+ g_error("Unable to export skeleton on path '%s': %s", powerd_source->priv->path,
+ error->message);
+ g_error_free(error);
+ error = NULL;
+ powerd_exit();
+ }
+
+ g_signal_connect(G_OBJECT(powerd_source->priv->skel), "handle-request-sys-state",
+ G_CALLBACK(handle_request_sys_state), powerd_source);
+ g_signal_connect(G_OBJECT(powerd_source->priv->skel), "handle-clear-sys-state",
+ G_CALLBACK(handle_clear_sys_state), powerd_source);
+ g_signal_connect(G_OBJECT(powerd_source->priv->skel), "handle-list-sys-requests",
+ G_CALLBACK(handle_list_sys_requests), powerd_source);
+
+ powerd_dbus_init_complete();
+}
+
+void
+powerd_name_acquired_cb (GDBusConnection *connection,
+ const gchar *name,
+ gpointer user_data)
+{
+ g_debug("name acquired (%s)", name);
+}
+
+void
+powerd_name_lost_cb (GDBusConnection *connection,
+ const gchar *name,
+ gpointer user_data)
+{
+ g_warning("name lost (%s)", name);
+ //XXX - quit here
+}
+
+void
+powerd_sys_state_signal_emit (enum SysPowerStates state)
+{
+ GError *error = NULL;
+
+ /* Make sure dbus has been set up */
+ if (!powerd_source)
+ return;
+
+ g_debug("Emitting signal for transition to state %s (%d)",
+ state_to_string(state), state);
+ g_dbus_connection_emit_signal(
+ POWERD_SOURCE_GET_PRIVATE(powerd_source)->system_bus,
+ NULL, /* destination */
+ "/com/canonical/powerd",
+ "com.canonical.powerd",
+ "SysPowerStateChange",
+ g_variant_new("(i)", state),
+ &error);
+ if (error) {
+ g_warning("Unable to signal a state change update: %s", error->message);
+ g_error_free(error);
+ }
+}
+
+void
+ofono_proxy_connect_cb(GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ GError *error = NULL;
+ GDBusProxy *ofono_proxy = NULL;
+ g_debug("ofono_proxy_async called");
+
+ ofono_proxy = g_dbus_proxy_new_finish (res, &error);
+ if (error) {
+ g_warning("ofono_proxy_finish failed: %s", error->message);
+ g_error_free(error);
+ }
+ else {
+ g_signal_connect(ofono_proxy, "g-signal", G_CALLBACK (on_ofono_signal), NULL);
+ g_debug("ofono_proxy_finish succeeded");
+ }
+}
diff -Nru powerd-0.5bzr9raring0/src/powerd-object.h powerd-0.12/src/powerd-object.h
--- powerd-0.5bzr9raring0/src/powerd-object.h 1970-01-01 00:00:00.000000000 +0000
+++ powerd-0.12/src/powerd-object.h 2013-06-03 17:17:09.000000000 +0000
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2013 Canonical Ltd.
+ *
+ * This file is part of powerd.
+ *
+ * powerd is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 3.
+ *
+ * powerd is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef __POWERD_OBJECT_H__
+#define __POWERD_OBJECT_H__
+
+#include
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+G_BEGIN_DECLS
+
+#define POWERD_TYPE_SOURCE (powerd_source_get_type ())
+#define POWERD_SOURCE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), POWERD_TYPE_SOURCE, PowerdSource))
+#define POWERD_IS_SOURCE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), POWERD_TYPE_SOURCE))
+#define POWERD_SOURCE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), POWERD_TYPE_SOURCE, PowerdSourceClass))
+#define POWERD_IS_SOURCE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), POWERD_TYPE_SOURCE))
+#define POWERD_SOURCE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), POWERD_TYPE_SOURCE, PowerdSourceClass))
+
+struct _PowerdSourcePrivate;
+
+typedef struct _PowerdSource PowerdSource;
+typedef struct _PowerdSourceClass PowerdSourceClass;
+typedef struct _PowerdSourcePrivate PowerdSourcePrivate;
+
+struct _PowerdSourceClass {
+ GObjectClass parent_class;
+};
+
+struct _PowerdSource {
+ GObject parent;
+ PowerdSourcePrivate * priv;
+};
+
+GType powerd_source_get_type (void);
+
+G_END_DECLS
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff -Nru powerd-0.5bzr9raring0/src/powerd-sensors.cpp powerd-0.12/src/powerd-sensors.cpp
--- powerd-0.5bzr9raring0/src/powerd-sensors.cpp 1970-01-01 00:00:00.000000000 +0000
+++ powerd-0.12/src/powerd-sensors.cpp 2013-06-03 20:32:24.000000000 +0000
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2013 Canonical Ltd.
+ *
+ * Authors:
+ * Ricardo Mendoza: ricardo.mendoza@canonical.com
+ *
+ * This file is part of powerd.
+ *
+ * powerd is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 3.
+ *
+ * powerd is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include "powerd-internal.h"
+#include "powerd-sensors.h"
+
+#include
+
+UASensorsProximity* prox_sensor;
+
+void on_new_proximity_event(UASProximityEvent *event, void *context)
+{
+ switch (uas_proximity_event_get_distance(event))
+ {
+ case U_PROXIMITY_NEAR:
+ {
+ powerd_set_display_state(POWERD_DISPLAY_OFF);
+ break;
+ }
+ case U_PROXIMITY_FAR:
+ {
+ powerd_set_display_state(POWERD_DISPLAY_ON);
+ break;
+ }
+ }
+}
+
+void powerd_sensors_proximity_enable(void)
+{
+ ua_sensors_proximity_enable(prox_sensor);
+}
+
+void powerd_sensors_proximity_disable(void)
+{
+ ua_sensors_proximity_disable(prox_sensor);
+}
+
+void powerd_sensors_init(void)
+{
+ prox_sensor = ua_sensors_proximity_new();
+
+ if (prox_sensor != NULL) {
+ ua_sensors_proximity_set_reading_cb(prox_sensor,
+ on_new_proximity_event,
+ NULL);
+ }
+}
diff -Nru powerd-0.5bzr9raring0/src/powerd-sensors.h powerd-0.12/src/powerd-sensors.h
--- powerd-0.5bzr9raring0/src/powerd-sensors.h 1970-01-01 00:00:00.000000000 +0000
+++ powerd-0.12/src/powerd-sensors.h 2013-06-03 17:17:09.000000000 +0000
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2013 Canonical Ltd.
+ *
+ * Authors:
+ * Ricardo Mendoza: ricardo.mendoza@canonical.com
+ *
+ * This file is part of powerd.
+ *
+ * powerd is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 3.
+ *
+ * powerd is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef __POWERD_SENSORS_H__
+#define __POWERD_SENSORS_H__
+
+void powerd_sensors_init(void);
+void powerd_sensors_proximity_enable(void);
+void powerd_sensors_proximity_disable(void);
+
+#endif /* __POWERD_SENSORS_H */
diff -Nru powerd-0.5bzr9raring0/src/powerd.cpp powerd-0.12/src/powerd.cpp
--- powerd-0.5bzr9raring0/src/powerd.cpp 2013-03-21 13:44:57.000000000 +0000
+++ powerd-0.12/src/powerd.cpp 2013-06-03 17:17:09.000000000 +0000
@@ -1,6 +1,11 @@
/*
* Copyright 2013 Canonical Ltd.
*
+ * Authors:
+ * Michael Frey: michael.frey@canonical.com
+ * Matthew Fischer: matthew.fischer@canonical.com
+ * Seth Forshee: seth.forshee@canonical.com
+ *
* This file is part of powerd.
*
* powerd is free software; you can redistribute it and/or modify
@@ -17,7 +22,6 @@
*/
#include
-#include
#include
#include
@@ -27,38 +31,33 @@
#include
#include
#include
+#include
+
+#include
+#include
+#include "powerd-internal.h"
+#include "powerd-object.h"
+#include "powerd-dbus.h"
+#include "powerd-sensors.h"
#include
#include
#include
+#include "libsuspend.h"
+
namespace
{
-enum {
- ACQUIRE_PARTIAL_WAKE_LOCK = 0,
- RELEASE_WAKE_LOCK,
- REQUEST_STATE,
- OUR_FD_COUNT
-};
-
-const char * const PATHS[] = {
- "/sys/power/wake_lock",
- "/sys/power/wake_unlock",
- "/sys/power/state"
-};
-
-static const char *off_state = "mem";
-static const char *on_state = "on";
-
-static bool in_suspend = false;
-static int g_initialized = 0;
-static int g_fds[OUR_FD_COUNT];
-static int g_error = 1;
-
static uint button_timer = 0;
+
+/*
+ * Do not modify activity_timer directly. Instead, call
+ * reset_activity_timer();
+ */
static uint activity_timer = 0;
+GMutex activity_timer_mutex;
static time_t curtime;
static int lasttime;
@@ -67,7 +66,11 @@
static gint saved_brightness = 255;
static gchar *brightness_path;
-static int ACTIVITY_TIMEOUT = 30;
+/* The real default for this is set in the gschema file, but set 30 here
+ * as a sanity check */
+static int activity_timeout = 30;
+static GMainLoop *main_loop = NULL;
+static guint name_id;
enum state {
BUTTON_DOWN,
@@ -77,200 +80,47 @@
static state button_state = BUTTON_UP;
-
-void get_brightness_path (void)
-{
- GUdevClient *client;
- GList *devices;
- GList *device;
- const gchar *device_type;
-
- // detect device
- client = g_udev_client_new (NULL);
- devices = g_udev_client_query_by_subsystem (client, "backlight");
- if (devices == NULL) {
- g_warning ("Fail to query backlight devices.");
- g_object_unref (client);
- return;
- }
-
- for (device = devices; device != NULL; device = device->next) {
- device_type = g_udev_device_get_sysfs_attr ((GUdevDevice *)device->data, "type");
- if ((g_strcmp0 (device_type, "firmware") == 0) ||
- (g_strcmp0 (device_type, "platform") == 0) ||
- (g_strcmp0 (device_type, "raw") == 0)) {
- brightness_path = g_strdup (g_udev_device_get_sysfs_path ((GUdevDevice *)device->data));
- g_print ("found: %s\n", brightness_path);
- break;
- }
- }
- g_print ("found2: %s\n", brightness_path);
-
- g_list_foreach (devices, (GFunc) g_object_unref, NULL);
- g_list_free (devices);
-
- g_object_unref (client);
-}
-
-
-void
-brightness_set_value (gint value)
-{
- gint fd;
- gchar *filename;
- gchar *svalue;
- gint length;
-
- filename = g_build_filename (brightness_path, "brightness", NULL);
- fd = open(filename, O_WRONLY);
- if (fd < 0) {
- g_warning ("Fail to set brightness.");
- g_free (filename);
- return;
- }
-
- svalue = g_strdup_printf ("%i", value);
- length = strlen (svalue);
-
- if (write (fd, svalue, length) != length) {
- g_warning ("Fail to write brightness information.");
- }
-
- close (fd);
- g_free (svalue);
- g_free (filename);
-}
-
-gint
-brightness_get_value (void)
-{
- GError *error;
- gchar *svalue;
- gint value;
- gchar *filename;
-
- svalue = NULL;
- error = NULL;
- filename = g_build_filename (brightness_path, "brightness", NULL);
- g_file_get_contents (filename, &svalue, NULL, &error);
- if (error) {
- g_warning ("Fail to get brightness value: %s", error->message);
- value = -1;
- g_error_free (error);
- } else {
- value = atoi (svalue);
- }
-
- g_free (filename);
-
- return value;
-
-}
-
-static int
-open_file_descriptors(const char * const paths[])
-{
- int i;
- for (i=0; i 0) {
- g_source_remove(activity_timer);
- activity_timer = 0;
- }
- saved_brightness = brightness_get_value();
- brightness_set_value(0);
- sf_blank(0);
- len = snprintf(buf, sizeof(buf), "%s", off_state);
- in_suspend = true;
- }
-
- buf[sizeof(buf) - 1] = '\0';
- len = write(g_fds[REQUEST_STATE], buf, len);
- if(len < 0) {
- failure:
- printf("Failed setting last user activity: g_error=%d\n", g_error);
- }
-
- //Need to wait for system wakeup otherwise we will get
- //permission denied if we try to ake the screen up before that.
- if (!in_suspend) {
- sleep(1);
- sf_unblank(0);
- brightness_set_value(saved_brightness);
- }
-
- return 0;
+ powerd_set_display_state(POWERD_DISPLAY_OFF);
}
-
void on_new_event(Event* event, void* context)
{
-
- if (activity_timer > 0) {
- g_source_remove(activity_timer);
- activity_timer = 0;
- }
-
switch(event->type)
{
case KEY_EVENT_TYPE:
if (event->details.key.key_code == ISCL_KEYCODE_POWER && button_state != SHUTDOWN) {
if (event->action == 1) {
+ g_debug("power button pressed");
button_state = BUTTON_UP;
curtime = time(0);
tm = localtime (&curtime);
- if (tm->tm_sec - lasttime < 2)
- set_screen_state();
+ if (tm->tm_sec - lasttime < 2) {
+ enum powerd_display_state new_state;
+ if (powerd_get_display_state() == POWERD_DISPLAY_OFF)
+ new_state = POWERD_DISPLAY_ON;
+ else
+ new_state = POWERD_DISPLAY_OFF;
+ powerd_set_display_state(new_state);
+ }
} else if (event->action == 0) {
button_state = BUTTON_DOWN;
curtime = time(0);
@@ -278,7 +128,7 @@
lasttime = tm->tm_sec;
if (button_timer > 0)
{
- g_source_remove(button_timer);
+ g_source_remove(button_timer);
button_timer = 0;
}
button_timer = g_timeout_add_seconds(2, call_shutdown, NULL);
@@ -286,19 +136,123 @@
}
break;
default:
+ powerd_reset_activity_timer(1);
break;
}
}
+void powerd_exit(void)
+{
+ g_main_loop_quit(main_loop);
+}
+
+static void
+sigterm_quit(int signal)
+{
+ g_warning("SIGTERM recieved, cleaning up");
+ // XXX - strangely this call to unown name claims the id is invalid
+ // but I'm sure we're using it properly
+ g_bus_unown_name(name_id);
+ g_main_loop_quit(main_loop);
+}
+
+} //namespace
+
+void powerd_reset_activity_timer(int add)
+{
+ g_mutex_lock(&activity_timer_mutex);
+ if (activity_timer > 0) {
+ g_source_remove(activity_timer);
+ activity_timer = 0;
+ }
+ if (add)
+ activity_timer = g_timeout_add_seconds(activity_timeout, activity_monitor, NULL);
+ g_mutex_unlock(&activity_timer_mutex);
+}
+
+/*
+ * Once dbus is ready, force the screen on to make the system state
+ * match the powerd iternal state
+ */
+void powerd_dbus_init_complete(void)
+{
+ powerd_set_display_state(POWERD_DISPLAY_ON);
+}
+
+void
+on_ofono_signal (GDBusProxy *proxy,
+ gchar *sender_name,
+ gchar *signal_name,
+ GVariant *parameters,
+ gpointer user_data)
+{
+ g_debug("we get signal from %s: %s", sender_name, signal_name);
+ if (!strcmp(signal_name, "IncomingMessage")) {
+ g_debug("Waking up the device - Incoming SMS");
+ powerd_reset_activity_timer(1);
+ powerd_set_display_state(POWERD_DISPLAY_ON);
+ }
+ else if (!strcmp(signal_name, "CallAdded")) {
+ g_debug("Waking up the device - Incoming Call");
+ powerd_reset_activity_timer(1);
+ powerd_set_display_state(POWERD_DISPLAY_ON);
+ powerd_sensors_proximity_enable();
+ }
+ else if (!strcmp(signal_name, "CallRemoved")) {
+ g_debug("Call over");
+ powerd_sensors_proximity_disable();
+ }
}
+static int
+get_activity_timeout_from_gsettings()
+{
+ GSettings *settings = NULL;
+ GVariant *val = NULL;
+ settings = g_settings_new("com.canonical.powerd");
+ val = g_settings_get_value(settings, "activity-timeout");
+ return g_variant_get_uint32(val);
+}
int main(int argc, char** argv)
{
+ int i, ret;
- GMainLoop* main_loop = NULL;
+ name_id = g_bus_own_name(G_BUS_TYPE_SYSTEM, "com.canonical.powerd",
+ G_BUS_NAME_OWNER_FLAGS_REPLACE, powerd_bus_acquired_cb,
+ powerd_name_acquired_cb, powerd_name_lost_cb, NULL, NULL);
+ g_debug("owner id: %u", name_id);
+
+ g_dbus_proxy_new_for_bus(G_BUS_TYPE_SYSTEM,
+ G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES,
+ NULL,
+ "org.ofono",
+ "/ril_0",
+ "org.ofono.MessageManager",
+ NULL,
+ (GAsyncReadyCallback)ofono_proxy_connect_cb,
+ NULL);
+
+ g_dbus_proxy_new_for_bus(G_BUS_TYPE_SYSTEM,
+ G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES,
+ NULL,
+ "org.ofono",
+ "/ril_0",
+ "org.ofono.VoiceCallManager",
+ NULL,
+ (GAsyncReadyCallback)ofono_proxy_connect_cb,
+ NULL);
+
+ activity_timeout = get_activity_timeout_from_gsettings();
+ g_debug("Activity Timeout is %d seconds\n", activity_timeout);
+
+ libsuspend_init(0);
+ power_request_init();
+ powerd_display_init();
+ powerd_sensors_init();
main_loop = g_main_loop_new (NULL, FALSE);
+ signal(SIGTERM, sigterm_quit);
AndroidEventListener listener;
listener.on_new_event = on_new_event;
@@ -312,11 +266,15 @@
android_input_stack_initialize(&listener, &config);
android_input_stack_start();
- g_type_init();
- get_brightness_path();
+ powerd_reset_activity_timer(1);
+
g_main_loop_run(main_loop);
+ g_bus_unown_name(name_id);
+ g_main_loop_unref(main_loop);
android_input_stack_stop();
android_input_stack_shutdown();
-}
+ power_request_deinit();
+ return 0;
+}
diff -Nru powerd-0.5bzr9raring0/src/powerd.h powerd-0.12/src/powerd.h
--- powerd-0.5bzr9raring0/src/powerd.h 1970-01-01 00:00:00.000000000 +0000
+++ powerd-0.12/src/powerd.h 2013-06-03 17:17:09.000000000 +0000
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2013 Canonical Ltd.
+ *
+ * This file is part of powerd.
+ *
+ * powerd is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 3.
+ *
+ * powerd is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef __POWERD_H__
+#define __POWERD_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+enum SysPowerStates {
+ //Note that callers will be notified of suspend state changes
+ //but may not request this state.
+ POWERD_SYS_STATE_SUSPEND = 0,
+
+ //The Active state will prevent system suspend
+ POWERD_SYS_STATE_ACTIVE,
+
+ POWERD_NUM_POWER_STATES
+};
+
+/*
+ * Clients should treat this as an opaque type. Though this isn't really
+ * possible until the client library is written.
+ */
+typedef char powerd_cookie_t[37];
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif