[Sugar-devel] [PATCH Sugar] Inhibit power suspend while playing text to speech - OLPC #11830

godiard at sugarlabs.org godiard at sugarlabs.org
Wed May 9 11:17:47 EDT 2012


From: Gonzalo Odiard <godiard at gmail.com>

To avoid stoping playing the text when the xo go to sleep.
This patch creates a file in /var/run/powerd-inhibit-suspend/
and remove it when finish. Is the same technique used in activities
(the code is copied from Distance activity) but we need decide
if is the right thing to do in sugar.

Signed-off-by: Gonzalo Odiard <gonzalo at laptop.org>
---
 src/jarabe/model/speech.py |   69 ++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 63 insertions(+), 6 deletions(-)

diff --git a/src/jarabe/model/speech.py b/src/jarabe/model/speech.py
index 1cb0ad4..24f4152 100644
--- a/src/jarabe/model/speech.py
+++ b/src/jarabe/model/speech.py
@@ -21,6 +21,7 @@ import gconf
 import gst
 import gtk
 import gobject
+import dbus
 
 
 DEFAULT_PITCH = 0
@@ -30,6 +31,10 @@ DEFAULT_RATE = 0
 
 _speech_manager = None
 
+# directory exists if powerd is running.  create a file here,
+# named after our pid, to inhibit suspend.
+POWERD_INHIBIT_DIR = '/var/run/powerd-inhibit-suspend'
+
 
 class SpeechManager(gobject.GObject):
 
@@ -138,7 +143,20 @@ class _GstSpeechPlayer(gobject.GObject):
         gobject.GObject.__init__(self)
         self._pipeline = None
 
+        self.using_powerd = False
+        if not self.powerd_running():
+            try:
+                bus = dbus.SystemBus()
+                proxy = bus.get_object('org.freedesktop.ohm',
+                                       '/org/freedesktop/ohm/Keystore')
+                self.ohm_keystore = dbus.Interface(
+                    proxy, 'org.freedesktop.ohm.Keystore')
+            except dbus.DBusException, e:
+                logging.warning("Error setting OHM inhibit: %s", e)
+                self.ohm_keystore = None
+
     def restart_sound_device(self):
+        self._inhibit_suspend()
         if self._pipeline is None:
             logging.debug('Trying to restart not initialized sound device')
             return
@@ -147,6 +165,7 @@ class _GstSpeechPlayer(gobject.GObject):
         self.emit('play')
 
     def pause_sound_device(self):
+        self._allow_suspend()
         if self._pipeline is None:
             return
 
@@ -154,6 +173,7 @@ class _GstSpeechPlayer(gobject.GObject):
         self.emit('pause')
 
     def stop_sound_device(self):
+        self._allow_suspend()
         if self._pipeline is None:
             return
 
@@ -172,12 +192,9 @@ class _GstSpeechPlayer(gobject.GObject):
         bus.connect('message', self.__pipe_message_cb)
 
     def __pipe_message_cb(self, bus, message):
-        if message.type == gst.MESSAGE_EOS:
-            self._pipeline.set_state(gst.STATE_NULL)
-            self.emit('stop')
-        elif message.type == gst.MESSAGE_ERROR:
-            self._pipeline.set_state(gst.STATE_NULL)
-            self.emit('stop')
+        if message.type == gst.MESSAGE_EOS or \
+                message.type == gst.MESSAGE_ERROR:
+            self.stop_sound_device()
 
     def speak(self, pitch, rate, voice_name, text):
         # TODO workaround for http://bugs.sugarlabs.org/ticket/1801
@@ -223,6 +240,46 @@ class _GstSpeechPlayer(gobject.GObject):
                 locale, best)
         return best
 
+    def powerd_running(self):
+        self.using_powerd = os.access(POWERD_INHIBIT_DIR, os.W_OK)
+        logging.debug("using_powerd: %d", self.using_powerd)
+        return self.using_powerd
+
+    def _inhibit_suspend(self):
+        if self.using_powerd:
+            fd = open(POWERD_INHIBIT_DIR + "/%u" % os.getpid(), 'w')
+            logging.debug("inhibit_suspend file is %s" % \
+                                   POWERD_INHIBIT_DIR + "/%u" % os.getpid())
+            fd.close()
+            return True
+
+        if self.ohm_keystore is not None:
+            try:
+                self.ohm_keystore.SetKey('suspend.inhibit', 1)
+                return self.ohm_keystore.GetKey('suspend.inhibit')
+            except dbus.exceptions.DBusException:
+                logging.warning("failed to inhibit suspend")
+                return False
+        else:
+            return False
+
+    def _allow_suspend(self):
+        if self.using_powerd:
+            os.unlink(POWERD_INHIBIT_DIR + "/%u" % os.getpid())
+            logging.debug("allow_suspend unlinking %s" % \
+                                   POWERD_INHIBIT_DIR + "/%u" % os.getpid())
+            return True
+
+        if self.ohm_keystore is not None:
+            try:
+                self.ohm_keystore.SetKey('suspend.inhibit', 0)
+                return self.ohm_keystore.GetKey('suspend.inhibit')
+            except dbus.exceptions.DBusException:
+                logging.error("failed to allow suspend")
+                return False
+        else:
+            return False
+
 
 def get_speech_manager():
     global _speech_manager
-- 
1.7.10.1



More information about the Sugar-devel mailing list