3 # This file is part of Panucci.
4 # Copyright (c) 2008-2009 The Panucci Audiobook and Podcast Player Project
6 # Panucci is free software: you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation, either version 3 of the License, or
9 # (at your option) any later version.
11 # Panucci is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with Panucci. If not, see <http://www.gnu.org/licenses/>.
19 # from services.py -- Core Services for gPodder
20 # Thomas Perl <thp@perli.net> 2007-08-24
22 # 2009-02-13 - nikosapi: made ObservableService more Panucci-esque
25 from logging
import getLogger
27 # the following are only needed for __headphone_watcher
31 class ObservableService(object):
32 def __init__(self
, signal_names
=[], log
=None):
33 self
.__log
= getLogger('ObservableService') if log
is None else log
36 for signal
in signal_names
:
37 self
.observers
[signal
] = []
40 self
.__log
.warning('No signal names defined...')
42 def register(self
, signal_name
, observer
):
43 if signal_name
in self
.observers
:
44 if not observer
in self
.observers
[signal_name
]:
45 self
.observers
[signal_name
].append(observer
)
46 self
.__log
.debug( 'Registered "%s" as an observer for "%s"',
47 observer
.__name
__, signal_name
)
50 'Observer "%s" is already added to signal "%s"',
51 observer
.__name
__, signal_name
)
54 'Signal "%s" is not available for registration', signal_name
)
56 def unregister(self
, signal_name
, observer
):
57 if signal_name
in self
.observers
:
58 if observer
in self
.observers
[signal_name
]:
59 self
.observers
[signal_name
].remove(observer
)
60 self
.__log
.debug( 'Unregistered "%s" as an observer for "%s"',
61 observer
.__name
__, signal_name
)
64 'Observer "%s" could not be removed from signal "%s"',
65 observer
.__name
__, signal_name
)
68 'Signal "%s" is not available for un-registration.',
71 def notify(self
, signal_name
, *args
, **kwargs
):
72 caller
= kwargs
.get('caller')
73 caller
= 'UnknownCaller' if caller
is None else caller
.__name
__
76 if signal_name
in self
.observers
:
78 'Sending signal "%s" for caller "%s"', signal_name
, caller
)
81 for observer
in self
.observers
[signal_name
]:
82 rtn_value
&= bool(observer( *args
))
85 'Signal "%s" (from caller "%s") is not available '
86 'for notification', signal_name
, caller
)
91 HEADPHONE_SYS
= "/sys/devices/platform/gpio-switch/headphone/state"
93 class __headphone_watcher(ObservableService
):
94 """ A small service with one singnal that reports whether or not the
95 headphones are connected. Returns True if the headphones are connected,
96 False if they're not and None if it's not possible to determine the
99 signals
= [ 'headphone-status-changed', ]
101 def __init__(self
, sys_file
):
102 self
.__log
= getLogger('panucci.serivces.__headphone_watcher')
103 ObservableService
.__init
__(self
, self
.signals
, self
.__log
)
105 self
.__is
_connected
= None
107 if util
.platform
== util
.MAEMO
:
109 self
.__sys
_file
= open( sys_file
, 'r' )
110 self
.__is
_connected
= self
.__get
_state
_from
_fd
(self
.__sys
_file
)
111 gobject
.io_add_watch( self
.__sys
_file
, gobject
.IO_PRI
,
112 self
.__on
_status
_changed
)
114 self
.__log
.exception("Can't open headphone status file.")
117 def is_connected(self
):
118 return self
.__is
_connected
120 def __get_state_from_fd(self
, fd
):
122 state
= fd
.read().strip()
123 return state
== 'connected'
125 def __on_status_changed(self
, src
, cond
):
126 self
.__is
_connected
= self
.__get
_state
_from
_fd
( src
)
128 'Headphone state changed (is_connected=%s).', self
.__is
_connected
)
129 self
.notify( 'headphone-status-changed', self
.__is
_connected
,
130 caller
=self
.__on
_status
_changed
)
133 headphone_service
= __headphone_watcher(HEADPHONE_SYS
)