def _shutdown_subsystems(self):
        # cleanup internals
        if self._timer is not None and self._timer.active():
            self._timer.cancel()
        self._timer = None

        # shutdown middleware components
        dns_manager = DNSManager()
        account_manager = AccountManager()
        addressbook_manager = AddressbookManager()
        session_manager = SessionManager()
        procs = [
            proc.spawn(dns_manager.stop),
            proc.spawn(account_manager.stop),
            proc.spawn(addressbook_manager.stop),
            proc.spawn(session_manager.stop)
        ]
        proc.waitall(procs)

        # stop video device
        self.video_device.producer.close()

        # shutdown engine
        self.engine.stop()
        self.engine.join(timeout=5)

        # stop threads
        thread_manager = ThreadManager()
        thread_manager.stop()

        # stop the reactor
        reactor.stop()
Exemple #2
0
    def init(self):
        self._version = str(
            NSBundle.mainBundle().infoDictionary().objectForKey_(
                "CFBundleShortVersionString"))

        #first_start = not os.path.exists(ApplicationData.get('config'))

        Account.register_extension(AccountExtension)
        BonjourAccount.register_extension(BonjourAccountExtension)
        Contact.register_extension(BlinkContactExtension)
        ContactGroup.register_extension(BlinkContactGroupExtension)
        SIPSimpleSettings.register_extension(SIPSimpleSettingsExtension)

        self._app.start(FileStorage(ApplicationData.directory))
        self.init_configurations()

        # start session mgr
        SessionManager()
    def init(self):
        if NSApp.delegate().account_extension:
            Account.register_extension(NSApp.delegate().account_extension)
        else:
            Account.register_extension(AccountExtension)

        BonjourAccount.register_extension(BonjourAccountExtension)
        Contact.register_extension(BlinkContactExtension)
        Group.register_extension(BlinkGroupExtension)
        ContactURI.register_extension(BlinkContactURIExtension)
        if NSApp.delegate().general_extension:
            SIPSimpleSettings.register_extension(NSApp.delegate().general_extension)
        else:
            SIPSimpleSettings.register_extension(SIPSimpleSettingsExtension)

        app = AppKit.NSApplication.sharedApplication()
        self._app.start(FileStorage(ApplicationData.directory))

        # start session mgr
        SessionManager()
    def _initialize_subsystems(self):
        notification_center = NotificationCenter()

        with self._lock:
            stop_pending = self._stop_pending
            if stop_pending:
                self.state = 'stopping'
        if stop_pending:
            notification_center.post_notification('SIPApplicationWillEnd',
                                                  sender=self)
            # stop the subsystems we already started: threads, engine and reactor
            self.engine.stop()
            self.engine.join(timeout=5)
            thread_manager = ThreadManager()
            thread_manager.stop()
            reactor.stop()
            return

        account_manager = AccountManager()
        addressbook_manager = AddressbookManager()
        dns_manager = DNSManager()
        session_manager = SessionManager()
        settings = SIPSimpleSettings()

        xcap_client.DEFAULT_HEADERS = {'User-Agent': settings.user_agent}

        # initialize TLS
        self._initialize_tls()

        # initialize PJSIP internal resolver
        self.engine.set_nameservers(dns_manager.nameservers)

        # initialize audio objects
        alert_device = settings.audio.alert_device
        if alert_device not in (
                None, 'system_default'
        ) and alert_device not in self.engine.output_devices:
            alert_device = 'system_default'
        input_device = settings.audio.input_device
        if input_device not in (
                None, 'system_default'
        ) and input_device not in self.engine.input_devices:
            input_device = 'system_default'
        output_device = settings.audio.output_device
        if output_device not in (
                None, 'system_default'
        ) and output_device not in self.engine.output_devices:
            output_device = 'system_default'
        tail_length = settings.audio.echo_canceller.tail_length if settings.audio.echo_canceller.enabled else 0
        voice_mixer = AudioMixer(input_device, output_device,
                                 settings.audio.sample_rate, tail_length)
        voice_mixer.muted = settings.audio.muted
        self.voice_audio_device = AudioDevice(voice_mixer)
        self.voice_audio_bridge = RootAudioBridge(voice_mixer)
        self.voice_audio_bridge.add(self.voice_audio_device)
        alert_mixer = AudioMixer(None, alert_device,
                                 settings.audio.sample_rate, 0)
        if settings.audio.silent:
            alert_mixer.output_volume = 0
        self.alert_audio_device = AudioDevice(alert_mixer)
        self.alert_audio_bridge = RootAudioBridge(alert_mixer)
        self.alert_audio_bridge.add(self.alert_audio_device)

        settings.audio.input_device = voice_mixer.input_device
        settings.audio.output_device = voice_mixer.output_device
        settings.audio.alert_device = alert_mixer.output_device

        # initialize video
        self.video_device = VideoDevice(settings.video.device,
                                        settings.video.resolution,
                                        settings.video.framerate)
        self.video_device.muted = settings.video.muted
        settings.video.device = self.video_device.name
        self.engine.set_video_options(settings.video.resolution,
                                      settings.video.framerate,
                                      settings.video.max_bitrate)
        self.engine.set_h264_options(settings.video.h264.profile,
                                     settings.video.h264.level)

        # initialize instance id
        if not settings.instance_id:
            settings.instance_id = uuid4().urn

        # initialize path for ZRTP cache file
        if ISIPSimpleApplicationDataStorage.providedBy(self.storage):
            self.engine.zrtp_cache = os.path.join(self.storage.directory,
                                                  'zrtp.db')

        # save settings in case something was modified during startup
        settings.save()

        # initialize middleware components
        dns_manager.start()
        account_manager.start()
        addressbook_manager.start()
        session_manager.start()

        notification_center.add_observer(self,
                                         name='CFGSettingsObjectDidChange')
        notification_center.add_observer(self, name='DNSNameserversDidChange')
        notification_center.add_observer(self, name='SystemIPAddressDidChange')
        notification_center.add_observer(self, name='SystemDidWakeUpFromSleep')

        with self._lock:
            self.state = 'started'
            stop_pending = self._stop_pending

        notification_center.post_notification('SIPApplicationDidStart',
                                              sender=self)

        if stop_pending:
            self.stop()
Exemple #5
0
    def _addIncomingSession(self, session, streams, is_update_proposal):
        view = self.getItemView()
        self.sessions[session] = view
        settings = SIPSimpleSettings()
        stream_type_list = list(set(stream.type for stream in streams))

        if len(self.sessions) == 1:
            self.panel.setTitle_(u"Incoming Call from %s" % format_identity_to_string(session.remote_identity, check_contact=True, format='compact'))
            if settings.sounds.enable_speech_synthesizer:
                if stream_type_list == ["chat"]:
                    base_text = "Chat from %s"
                else:
                    base_text = "Call from %s"
                self.speak_text = base_text % format_identity_to_string(session.remote_identity, check_contact=True, format='compact')
                self.startSpeechSynthesizerTimer()
        else:
            self.panel.setTitle_(u"Multiple Incoming Calls")

        NotificationCenter().add_observer(self, sender=session)

        captionT = view.viewWithTag_(1)
        fromT = view.viewWithTag_(2)
        destT = view.viewWithTag_(3)
        acceptB = view.viewWithTag_(5)
        rejectB = view.viewWithTag_(7)
        otherB = view.viewWithTag_(6)
        busyB = view.viewWithTag_(8)
        photoImage = view.viewWithTag_(99)

        stream_types = [s.type for s in streams]

        session_manager = SessionManager()
        have_audio_call = any(s for s in session_manager.sessions if s is not session and s.streams and 'audio' in (stream.type for stream in s.streams))
        if not have_audio_call:
            self.startSpeechRecognition()

        typeCount = 0
        if 'audio' in stream_types:
            audioIcon = view.viewWithTag_(32)
            frame = audioIcon.frame()
            typeCount+= 1
            frame.origin.x = NSMaxX(view.frame()) - 10 - (NSWidth(frame) + 10) * typeCount
            audioIcon.setFrame_(frame)
            audioIcon.setHidden_(False)

            if not is_update_proposal:
                frame = view.frame()
                frame.size.height += 20 # give extra space for the counter label
                view.setFrame_(frame)
                if session.account.audio.auto_accept:
                    have_audio_call = any(s for s in session_manager.sessions if s is not session and s.streams and 'audio' in (stream.type for stream in s.streams))
                    if not have_audio_call:
                        self.enableAutoAnswer(view, session)
                elif SIPSimpleSettings().answering_machine.enabled:
                    self.enableAnsweringMachine(view, session)

        if 'chat' in stream_types:
            chatIcon = view.viewWithTag_(31)
            frame = chatIcon.frame()
            typeCount+= 1
            frame.origin.x = NSMaxX(view.frame()) - 10 - (NSWidth(frame) + 10) * typeCount
            chatIcon.setFrame_(frame)
            chatIcon.setHidden_(False)

        if 'desktop-sharing' in stream_types:
            desktopIcon = view.viewWithTag_(34)
            frame = desktopIcon.frame()
            typeCount+= 1
            frame.origin.x = NSMaxX(view.frame()) - 10 - (NSWidth(frame) + 10) * typeCount
            desktopIcon.setFrame_(frame)
            desktopIcon.setHidden_(False)

        is_file_transfer = False
        if 'file-transfer' in stream_types:
            is_file_transfer = True
            fileIcon = view.viewWithTag_(33)
            frame = fileIcon.frame()
            typeCount+= 1
            frame.origin.x = NSMaxX(view.frame()) - 10 - (NSWidth(frame) + 10) * typeCount
            fileIcon.setFrame_(frame)
            fileIcon.setHidden_(False)

        self.sessionsListView.addSubview_(view)
        frame = self.sessionsListView.frame()
        frame.origin.y = self.extraHeight - 14
        frame.size.height = self.sessionsListView.minimumHeight()
        self.sessionsListView.setFrame_(frame)
        height = frame.size.height + self.extraHeight
        size = NSMakeSize(NSWidth(self.panel.frame()), height)

        screenSize = NSScreen.mainScreen().frame().size
        if size.height > (screenSize.height * 2) / 3:
            size.height = (screenSize.height * 2) / 3

        frame = self.panel.frame()
        frame.size.height = size.height
        frame.size.height = NSHeight(self.panel.frameRectForContentRect_(frame))
        self.panel.setFrame_display_animate_(frame, True, True)
        self.sessionsListView.relayout()

        acceptB.cell().setRepresentedObject_(NSNumber.numberWithInt_(0))
        otherB.cell().setRepresentedObject_(NSNumber.numberWithInt_(1))
        rejectB.cell().setRepresentedObject_(NSNumber.numberWithInt_(2))
        busyB.cell().setRepresentedObject_(NSNumber.numberWithInt_(3))

        # no Busy or partial accept option for Stream Update Proposals
        busyB.setHidden_(is_update_proposal or is_file_transfer)
        otherB.setHidden_(is_update_proposal)
        if is_file_transfer:
            busyB.setAttributedTitle_("")

        panelAcceptB = self.panel.contentView().viewWithTag_(10)
        panelOtherB = self.panel.contentView().viewWithTag_(11)

        panelRejectB = self.panel.contentView().viewWithTag_(12)
        panelBusyB = self.panel.contentView().viewWithTag_(13)
        if is_update_proposal:
            subject, accept, other = self.format_subject_for_incoming_reinvite(session, streams)
            other = ""
        else:
            subject, accept, other = self.format_subject_for_incoming_invite(session, streams)
        captionT.setStringValue_(subject)

        frame = captionT.frame()
        frame.size.width = NSWidth(self.sessionsListView.frame()) - 80 - 40 * typeCount
        captionT.setFrame_(frame)

        caller_contact = NSApp.delegate().contactsWindowController.getContactMatchingURI(session.remote_identity.uri)
        if caller_contact:
            if caller_contact.icon:
                photoImage.setImage_(caller_contact.icon)

            if caller_contact.auto_answer:
                BlinkLogger().log_info(u"Auto answer enabled for this contact")
                self.enableAutoAnswer(view, session)

        fromT.setStringValue_(u"%s" % format_identity_to_string(session.remote_identity, check_contact=True, format='full'))
        fromT.sizeToFit()

        has_audio_streams = any(s for s in reduce(lambda a,b:a+b, [session.proposed_streams for session in self.sessions.keys()], []) if s.type=="audio")
        if has_audio_streams:
            outdev = SIPSimpleSettings().audio.output_device
            indev = SIPSimpleSettings().audio.input_device
            if outdev == u"system_default":
                outdev = u"System Default"
            if indev == u"system_default":
                indev = u"System Default"
            if outdev != indev:
                self.deviceLabel.setStringValue_(u"Selected Output Device is %s, Input is %s" % (outdev.strip(), indev.strip()))
            else:
                self.deviceLabel.setStringValue_(u"Selected Audio Device is %s" % outdev.strip())

            BlinkLogger().log_info(u"Selected audio input/output devices: %s/%s" % (indev, outdev))

            self.deviceLabel.sizeToFit()
            self.deviceLabel.setHidden_(False)
        else:
            self.deviceLabel.setHidden_(True)

        acceptB.setTitle_(accept or "")
        otherB.setTitle_(other or "")

        if False and sum(a.enabled for a in AccountManager().iter_accounts())==1:
            destT.setHidden_(True)
        else:
            destT.setHidden_(False)
            if isinstance(session.account, BonjourAccount):
                destT.setStringValue_(u"To Bonjour account")
            else:
                destT.setStringValue_(u"To %s" % format_identity_to_string(session.account))
            destT.sizeToFit()

        if len(self.sessions) == 1:
            panelAcceptB.setTitle_(accept)
            panelAcceptB.setHidden_(False)
            panelOtherB.setTitle_(other or "")
            panelOtherB.setHidden_(not other)
            panelRejectB.setTitle_("Reject")

            panelAcceptB.cell().setRepresentedObject_(NSNumber.numberWithInt_(0))
            panelRejectB.cell().setRepresentedObject_(NSNumber.numberWithInt_(2))
            panelBusyB.cell().setRepresentedObject_(NSNumber.numberWithInt_(3))
            panelOtherB.cell().setRepresentedObject_(NSNumber.numberWithInt_(1))

            panelBusyB.setHidden_(is_update_proposal or is_file_transfer)

            for i in (5, 6, 7, 8):
                view.viewWithTag_(i).setHidden_(True)
        else:
            panelAcceptB.setHidden_(False)
            panelAcceptB.setTitle_("Accept All")
            panelOtherB.setHidden_(True)
            panelBusyB.setHidden_(is_update_proposal or is_file_transfer)
            panelRejectB.setTitle_("Reject All")

            for v in self.sessions.values():
                for i in (5, 6, 7, 8):
                    btn = v.viewWithTag_(i)
                    btn.setHidden_(len(btn.attributedTitle()) == 0)