1# Copyright 2015 The Chromium OS Authors. All rights reserved. 2# Use of this source code is governed by a BSD-style license that can be 3# found in the LICENSE file. 4 5import logging 6import threading 7 8import dbus 9import dbus.mainloop.glib 10import gobject 11 12 13class DarkResumeListener(object): 14 """Server which listens for dark resume-related DBus signals to count how 15 many dark resumes we have seen since instantiation.""" 16 17 SIGNAL_NAME = 'DarkSuspendImminent' 18 19 20 def __init__(self): 21 dbus.mainloop.glib.threads_init() 22 gobject.threads_init() 23 24 dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) 25 self._bus = dbus.SystemBus() 26 self._count = 0 27 28 self._bus.add_signal_receiver(handler_function=self._saw_dark_resume, 29 signal_name=self.SIGNAL_NAME) 30 31 def loop_runner(): 32 """Handles DBus events on the system bus using the mainloop.""" 33 # If we just call run on this loop, the listener will hang and the test 34 # will never finish. Instead, we process events as they come in. This 35 # thread is set to daemon below, which means that the program will exit 36 # when the main thread exits. 37 loop = gobject.MainLoop() 38 context = loop.get_context() 39 while True: 40 context.iteration(True) 41 thread = threading.Thread(None, loop_runner) 42 thread.daemon = True 43 thread.start() 44 logging.debug('Dark resume listener started') 45 46 47 @property 48 def count(self): 49 """Number of DarkSuspendImminent events this listener has seen since its 50 creation.""" 51 return self._count 52 53 54 def _saw_dark_resume(self, unused): 55 self._count += 1 56