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