Hoping to get calls working on Maemo 5 by adding these undocumented attributes that...
[theonering] / src / channel / call.py
1 import logging
2
3 import dbus
4 import gobject
5 import telepathy
6
7 import tp
8 import gtk_toolbox
9
10
11 _moduleLogger = logging.getLogger("channel.call")
12
13
14 class CallChannel(
15                 tp.ChannelTypeStreamedMedia,
16                 tp.ChannelInterfaceCallState,
17                 tp.ChannelInterfaceGroup,
18         ):
19         # @bug On Maemo 5 this is having some kind of "General" error, possibly due to an issue with "GetAll" DBusProperties stuff
20
21         def __init__(self, connection, manager, props, contactHandle):
22                 self.__manager = manager
23                 self.__props = props
24                 self.__cancelId = None
25
26                 if telepathy.interfaces.CHANNEL_INTERFACE + '.InitiatorHandle' in props:
27                         self._initiator = connection.get_handle_by_id(
28                                 telepathy.HANDLE_TYPE_CONTACT,
29                                 props[telepathy.interfaces.CHANNEL_INTERFACE + '.InitiatorHandle'],
30                         )
31                 elif telepathy.interfaces.CHANNEL_INTERFACE + '.InitiatorID' in props:
32                         self._initiator = connection.get_handle_by_name(
33                                 telepathy.HANDLE_TYPE_CONTACT,
34                                 props[telepathy.interfaces.CHANNEL_INTERFACE + '.InitiatorHandle'],
35                         )
36                 else:
37                         _moduleLogger.warning('InitiatorID or InitiatorHandle not set on new channel')
38                         self._initiator = None
39
40                 tp.ChannelTypeStreamedMedia.__init__(self, connection, manager, props)
41                 tp.ChannelInterfaceCallState.__init__(self)
42                 tp.ChannelInterfaceGroup.__init__(self)
43                 self.__contactHandle = contactHandle
44                 self._implement_property_get(
45                         telepathy.interfaces.CHANNEL_TYPE_STREAMED_MEDIA,
46                         {
47                                 "InitialAudio": self.initial_audio,
48                                 "InitialVideo": self.initial_video,
49                         },
50                 )
51                 self._implement_property_get(
52                         telepathy.interfaces.CHANNEL_INTERFACE,
53                         {
54                                 'InitiatorHandle': lambda: dbus.UInt32(self._initiator.id),
55                                 'InitiatorID': lambda: self._initiator.name,
56                         },
57                 )
58
59                 self.GroupFlagsChanged(0, 0)
60                 self.MembersChanged(
61                         '', [self._conn.GetSelfHandle()], [], [], [contactHandle],
62                         0, telepathy.CHANNEL_GROUP_CHANGE_REASON_NONE
63                 )
64
65         def initial_audio(self):
66                 return False
67
68         def initial_video(self):
69                 return False
70
71         @gtk_toolbox.log_exception(_moduleLogger)
72         def Close(self):
73                 self.close()
74
75         def close(self):
76                 _moduleLogger.debug("Closing call")
77                 tp.ChannelTypeStreamedMedia.Close(self)
78                 self.remove_from_connection()
79                 if self.__cancelId is not None:
80                         gobject.source_remove(self.__cancelId)
81                         self.__cancelId = None
82
83         @gtk_toolbox.log_exception(_moduleLogger)
84         def GetLocalPendingMembersWithInfo(self):
85                 return []
86
87         @gtk_toolbox.log_exception(_moduleLogger)
88         def ListStreams(self):
89                 """
90                 For org.freedesktop.Telepathy.Channel.Type.StreamedMedia
91                 """
92                 return ()
93
94         @gtk_toolbox.log_exception(_moduleLogger)
95         def RemoveStreams(self, streams):
96                 """
97                 For org.freedesktop.Telepathy.Channel.Type.StreamedMedia
98                 """
99                 raise telepathy.errors.NotImplemented("Cannot remove a stream")
100
101         @gtk_toolbox.log_exception(_moduleLogger)
102         def RequestStreamDirection(self, stream, streamDirection):
103                 """
104                 For org.freedesktop.Telepathy.Channel.Type.StreamedMedia
105
106                 @note Since streams are short lived, not bothering to implement this
107                 """
108                 _moduleLogger.info("A request was made to change the stream direction")
109                 raise telepathy.errors.NotImplemented("Cannot change directions")
110
111         @gtk_toolbox.log_exception(_moduleLogger)
112         def RequestStreams(self, contactId, streamTypes):
113                 """
114                 For org.freedesktop.Telepathy.Channel.Type.StreamedMedia
115
116                 @returns [(Stream ID, contact, stream type, stream state, stream direction, pending send flags)]
117                 """
118                 contact = self._conn.get_handle_by_id(telepathy.constants.HANDLE_TYPE_CONTACT, contactId)
119                 assert self.__contactHandle == contact, "%r != %r" % (self.__contactHandle, contact)
120                 contactNumber = contact.phoneNumber
121
122                 self.CallStateChanged(self.__contactHandle, telepathy.constants.CHANNEL_CALL_STATE_RINGING)
123                 self.__cancelId = gobject.idle_add(self._on_cancel)
124                 self._conn.session.backend.call(contactNumber)
125
126                 streamId = 0
127                 streamState = telepathy.constants.MEDIA_STREAM_STATE_DISCONNECTED
128                 streamDirection = telepathy.constants.MEDIA_STREAM_DIRECTION_BIDIRECTIONAL
129                 pendingSendFlags = telepathy.constants.MEDIA_STREAM_PENDING_REMOTE_SEND
130                 return [(streamId, contact, streamTypes[0], streamState, streamDirection, pendingSendFlags)]
131
132         @gtk_toolbox.log_exception(_moduleLogger)
133         def GetCallStates(self):
134                 """
135                 For org.freedesktop.Telepathy.Channel.Interface.CallState
136
137                 Get the current call states for all contacts involved in this call. 
138                 @returns {Contact: telepathy.constants.CHANNEL_CALL_STATE_*}
139                 """
140                 return {self.__contactHandle: telepathy.constants.CHANNEL_CALL_STATE_FORWARDED}
141
142         @gtk_toolbox.log_exception(_moduleLogger)
143         def _on_cancel(self, *args):
144                 self.CallStateChanged(self.__contactHandle, telepathy.constants.CHANNEL_CALL_STATE_FORWARDED)
145                 self.close()
146                 self.__cancelId = None
147                 return False