Skip to content

Commit

Permalink
Merge pull request #61 from plundstr/next
Browse files Browse the repository at this point in the history
Added vibra feedback to shutdown
  • Loading branch information
Pekka Lundstrom committed Mar 12, 2014
2 parents 915a027 + 07721a2 commit e041c8b
Show file tree
Hide file tree
Showing 5 changed files with 241 additions and 0 deletions.
16 changes: 16 additions & 0 deletions configure.ac
Expand Up @@ -156,6 +156,19 @@ AS_IF([test "x$enable_bootreason_logger" != xno],
[AC_DEFINE([DSME_BOOTREASON_LOGGER], [1])])
AM_CONDITIONAL([WANT_BOOTREASON_LOGGER], [test x$enable_bootreason_logger != xno])

#
# Shutdown feedback
#
AC_ARG_ENABLE([shutdown-feedback],
[AS_HELP_STRING([--disable-shutdown-feedback],
[disable bootreason logger (libshutdownfeedback)])],
[],
[enable_shutdown_feedback=yes])

AS_IF([test "x$enable_shutdown_feedback" != xno],
[AC_DEFINE([DSME_SHUTDOWN_FEEDBACK], [1])])
AM_CONDITIONAL([WANT_SHUTDOWN_FEEDBACK], [test x$enable_shutdown_feedback != xno])

#
# Compiler and linker flags
#
Expand Down Expand Up @@ -198,6 +211,9 @@ AM_PROG_CC_C_O()
PKG_CHECK_MODULES(GLIB, glib-2.0)
PKG_CHECK_MODULES(DBUS, dbus-1)
PKG_CHECK_MODULES(DBUSGLIB, dbus-glib-1)
if test "x$enable_shutdown_feedback" != xno; then
PKG_CHECK_MODULES(LIBNGF, libngf0)
fi

# Check libs (that are not yet checked)
# Whitespaces in 'action-if-found' fields in order to not (auto)update LIBS variable
Expand Down
10 changes: 10 additions & 0 deletions modules/Makefile.am
Expand Up @@ -75,6 +75,10 @@ if WANT_BOOTREASON_LOGGER
pkglib_LTLIBRARIES += bootreasonlogger.la
endif

if WANT_SHUTDOWN_FEEDBACK
pkglib_LTLIBRARIES += shutdownfeedback.la
endif

startup_la_SOURCES = startup.c

# TODO: remove this
Expand Down Expand Up @@ -199,3 +203,9 @@ bootreasonlogger_la_SOURCES = bootreasonlogger.c
bootreasonlogger_la_CFLAGS = $(AM_CFLAGS) $(GLIB_CFLAGS) $(DBUS_CFLAGS) -D_GNU_SOURCE
bootreasonlogger_la_LIBADD = $(GLIB_LIBS)
endif

if WANT_SHUTDOWN_FEEDBACK
shutdownfeedback_la_SOURCES = shutdownfeedback.c
shutdownfeedback_la_CFLAGS = $(AM_CFLAGS) $(GLIB_CFLAGS) $(DBUS_CFLAGS) $(LIBNGF_CFLAGS) -D_GNU_SOURCE
shutdownfeedback_la_LIBADD = $(GLIB_LIBS) $(LIBNGF_LIBS)
endif
210 changes: 210 additions & 0 deletions modules/shutdownfeedback.c
@@ -0,0 +1,210 @@
/**
@file shutdownfeedback.c
Play vibra when shutting down
<p>
Copyright (C) 2013 Jolla Oy.
@author Pekka Lundstrom <pekka.lundstrom@jolla.com>
This file is part of Dsme.
Dsme is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License
version 2.1 as published by the Free Software Foundation.
Dsme 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with Dsme. If not, see <http://www.gnu.org/licenses/>.
*/

#include "dbusproxy.h"
#include "dsme_dbus.h"

#include "dsme/modules.h"
#include "dsme/logging.h"

#include <dsme/state.h>
#include <dsme/protocol.h>

#include <libngf/ngf.h>
#include <stdio.h>
#include <stdlib.h>

#include <glib.h>
#include <dbus/dbus.h>
#include <dbus/dbus-glib-lowlevel.h>

#define PFIX "shutdownfeedback: "
#define NGF_PWROFF_EVENT "pwroff"
static NgfClient *ngf_client = NULL;
static DBusConnection *dbus_connection = NULL;
static uint32_t playing_event_id = 0;

static void ngf_callback(NgfClient *client, uint32_t id, NgfEventState state, void *data);

static void create_ngf_client(void)
{
if (ngf_client) {
/* We already have a connection */
return;
}

if (!dbus_connection) {
dsme_log(LOG_WARNING, PFIX"No dbus connection. Can't connect to ngf");
return;
}

if ((ngf_client = ngf_client_create(NGF_TRANSPORT_DBUS, dbus_connection)) == NULL) {
dsme_log(LOG_ERR, PFIX"Can't create ngf client");
} else {
ngf_client_set_callback(ngf_client, ngf_callback, NULL);
}
}

static void destroy_ngf_client(void)
{
/* we should do something like this *
* if (ngf_client) {
* ngf_client_destroy(ngf_client);
* ngf_client = NULL;
* playing_event_id = 0;
* }
* but shutdown is already going, ngfd is already down, same as dbus
* so there is no point of doing clean destroy.
* Let system go down and forget about destroy
*/
}

static void
ngf_callback(NgfClient *client, uint32_t event_id, NgfEventState state, void *userdata)
{
(void) client;
(void) userdata;
const char *state_name;
bool play_done = false;

switch (state) {
case NGF_EVENT_FAILED:
state_name = "Failed";
play_done = true;
break;
case NGF_EVENT_COMPLETED:
state_name = "Completed";
play_done = true;
break;
case NGF_EVENT_PLAYING:
state_name = "Playing"; break;
case NGF_EVENT_PAUSED:
state_name = "Paused"; break;
case NGF_EVENT_BUSY:
state_name = "Busy"; break;
case NGF_EVENT_LONG:
state_name = "Long"; break;
case NGF_EVENT_SHORT:
state_name = "Short"; break;
default:
state_name = "Unknown";
play_done = true;
break;
}
dsme_log(LOG_DEBUG, PFIX"%s(%s, %d)", __FUNCTION__, state_name, event_id);

if (play_done) {
playing_event_id = 0;
}
}

static void play_vibra(void)
{
static char event[] = NGF_PWROFF_EVENT;

if (playing_event_id) {
/* We already are playing an event, don't start new one */
// dsme_log(LOG_DEBUG, PFIX"Play already going, skip");
return;
}

if (!ngf_client) {
create_ngf_client();
}
if (!ngf_client) {
dsme_log(LOG_ERR, PFIX"Can't play vibra. We don't have ngf client");
return;
}

playing_event_id = ngf_client_play_event (ngf_client, event, NULL);
dsme_log(LOG_DEBUG, PFIX"PLAY(%s, %d)", event, playing_event_id);
}


DSME_HANDLER(DSM_MSGTYPE_STATE_CHANGE_IND, conn, msg)
{
if ((msg->state == DSME_STATE_SHUTDOWN) ||
(msg->state == DSME_STATE_REBOOT)) {
//dsme_log(LOG_DEBUG, PFIX"shutdown/reboot state received");
play_vibra();
}
}
DSME_HANDLER(DSM_MSGTYPE_REBOOT_REQ, conn, msg)
{
// dsme_log(LOG_DEBUG, PFIX"reboot reques received");
play_vibra();
}

DSME_HANDLER(DSM_MSGTYPE_SHUTDOWN_REQ, conn, msg)
{
//dsme_log(LOG_DEBUG, PFIX"shutdown reques received");
play_vibra();
}

DSME_HANDLER(DSM_MSGTYPE_DBUS_CONNECT, conn, msg)
{
DBusError err = DBUS_ERROR_INIT;

//dsme_log(LOG_INFO, PFIX"DBUS_CONNECT");
if (!(dbus_connection = dsme_dbus_get_connection(&err))) {
dsme_log(LOG_WARNING, PFIX"can't connect to systembus: %s: %s",
err.name, err.message);
goto cleanup;
}
dbus_connection_setup_with_g_main(dbus_connection, NULL);

cleanup:
dbus_error_free(&err);
}

DSME_HANDLER(DSM_MSGTYPE_DBUS_DISCONNECT, conn, msg)
{
//dsme_log(LOG_INFO, PFIX"DBUS_DISCONNECT");
destroy_ngf_client();
if (dbus_connection) {
dbus_connection_unref(dbus_connection);
dbus_connection = NULL;
}
}

module_fn_info_t message_handlers[] = {
DSME_HANDLER_BINDING(DSM_MSGTYPE_SHUTDOWN_REQ),
DSME_HANDLER_BINDING(DSM_MSGTYPE_REBOOT_REQ),
DSME_HANDLER_BINDING(DSM_MSGTYPE_STATE_CHANGE_IND),
DSME_HANDLER_BINDING(DSM_MSGTYPE_DBUS_CONNECT),
DSME_HANDLER_BINDING(DSM_MSGTYPE_DBUS_DISCONNECT),
{0}
};


void module_init(module_t* handle)
{
dsme_log(LOG_DEBUG, "shutdownfeedback.so loaded");
}

void module_fini(void)
{
dsme_log(LOG_DEBUG, "shutdownfeedback.so unloaded");
}
3 changes: 3 additions & 0 deletions modules/startup.c
Expand Up @@ -114,6 +114,9 @@ const char *modules[] = {
"dbusautoconnector.so",
#ifdef DSME_PWRKEY_MONITOR
"pwrkeymonitor.so",
#endif
#ifdef DSME_SHUTDOWN_FEEDBACK
"shutdownfeedback.so",
#endif
NULL
};
Expand Down
2 changes: 2 additions & 0 deletions rpm/dsme.spec
Expand Up @@ -10,6 +10,7 @@ Source1: dsme.service
Source2: dsme-rpmlintrc
Requires: systemd
Requires: statefs
Requires: ngfd
Requires(preun): systemd
Requires(post): systemd
Requires(postun): systemd
Expand All @@ -20,6 +21,7 @@ BuildRequires: pkgconfig(libiphb)
BuildRequires: pkgconfig(dsme) >= 0.62.0
BuildRequires: pkgconfig(systemd)
BuildRequires: pkgconfig(mce) >= 1.12.3
BuildRequires: pkgconfig(libngf0)
BuildRequires: python
BuildRequires: autoconf
BuildRequires: libtool
Expand Down

0 comments on commit e041c8b

Please sign in to comment.