Commit f31aa1da authored by Romain Bertozzi's avatar Romain Bertozzi

daemonservice: introduce service

This patch adds the deamon service to the project.

This service will handle the main capabilities of the Ring Daemon,
such as starting and stopping it.

For the moment, there is no callback, notifications, or observers to
that service. This let us the flexibility to implement it with
whatever we want in the future (Rx-like, NSNotifications etc...).

Tuleap: #1378
Change-Id: Ib560977f9fd1dacd45e2afc63613870a3d60630f
parent 966233f8
......@@ -17,6 +17,7 @@
02B22E011DF755E5000358C9 /* MainTabBarViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02B22E001DF755E5000358C9 /* MainTabBarViewController.swift */; };
02B22E031DF755F7000358C9 /* WalkthroughStoryboard.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 02B22E021DF755F7000358C9 /* WalkthroughStoryboard.storyboard */; };
02B22E051DF75605000358C9 /* NotificationNames.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02B22E041DF75605000358C9 /* NotificationNames.swift */; };
02B22E091DF7585F000358C9 /* DaemonService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02B22E081DF7585F000358C9 /* DaemonService.swift */; };
02E1A0251DDE4ABA00D75B59 /* BoolStringExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 043866371D2304A700E06CE2 /* BoolStringExtension.swift */; };
043866211D218B1100E06CE2 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 043866201D218B1100E06CE2 /* AudioToolbox.framework */; };
043866331D22CE8C00E06CE2 /* MeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 043866321D22CE8C00E06CE2 /* MeViewController.swift */; };
......@@ -35,7 +36,7 @@
04399A971D1C2F6100E99CD9 /* libbz2.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 04399A951D1C2F6100E99CD9 /* libbz2.tbd */; };
04399A981D1C2F6100E99CD9 /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 04399A961D1C2F6100E99CD9 /* libz.tbd */; };
04399AAC1D1C304300E99CD9 /* ConfigurationManagerAdaptator.mm in Sources */ = {isa = PBXBuildFile; fileRef = 04399AA61D1C304300E99CD9 /* ConfigurationManagerAdaptator.mm */; };
04399AAD1D1C304300E99CD9 /* DRingAdaptator.mm in Sources */ = {isa = PBXBuildFile; fileRef = 04399AA81D1C304300E99CD9 /* DRingAdaptator.mm */; };
04399AAD1D1C304300E99CD9 /* DRingAdapter.mm in Sources */ = {isa = PBXBuildFile; fileRef = 04399AA81D1C304300E99CD9 /* DRingAdapter.mm */; };
04399AAE1D1C304300E99CD9 /* Utils.mm in Sources */ = {isa = PBXBuildFile; fileRef = 04399AAB1D1C304300E99CD9 /* Utils.mm */; };
04399AE41D1C341A00E99CD9 /* libavcodec.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 04399AB21D1C341A00E99CD9 /* libavcodec.a */; };
04399AE51D1C341A00E99CD9 /* libavdevice.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 04399AB31D1C341A00E99CD9 /* libavdevice.a */; };
......@@ -114,6 +115,7 @@
02B22E001DF755E5000358C9 /* MainTabBarViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = MainTabBarViewController.swift; path = MainTabBar/MainTabBarViewController.swift; sourceTree = "<group>"; };
02B22E021DF755F7000358C9 /* WalkthroughStoryboard.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = WalkthroughStoryboard.storyboard; path = Walkthrough/WalkthroughStoryboard.storyboard; sourceTree = "<group>"; };
02B22E041DF75605000358C9 /* NotificationNames.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = NotificationNames.swift; path = Extensions/NotificationNames.swift; sourceTree = "<group>"; };
02B22E081DF7585F000358C9 /* DaemonService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = DaemonService.swift; path = Services/DaemonService.swift; sourceTree = "<group>"; };
043866201D218B1100E06CE2 /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; };
043866321D22CE8C00E06CE2 /* MeViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MeViewController.swift; sourceTree = "<group>"; };
043866351D22D06500E06CE2 /* AccountTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AccountTableViewCell.swift; sourceTree = "<group>"; };
......@@ -139,8 +141,8 @@
04399A961D1C2F6100E99CD9 /* libz.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = usr/lib/libz.tbd; sourceTree = SDKROOT; };
04399AA51D1C304300E99CD9 /* ConfigurationManagerAdaptator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ConfigurationManagerAdaptator.h; sourceTree = "<group>"; };
04399AA61D1C304300E99CD9 /* ConfigurationManagerAdaptator.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ConfigurationManagerAdaptator.mm; sourceTree = "<group>"; };
04399AA71D1C304300E99CD9 /* DRingAdaptator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DRingAdaptator.h; sourceTree = "<group>"; };
04399AA81D1C304300E99CD9 /* DRingAdaptator.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DRingAdaptator.mm; sourceTree = "<group>"; };
04399AA71D1C304300E99CD9 /* DRingAdapter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DRingAdapter.h; sourceTree = "<group>"; };
04399AA81D1C304300E99CD9 /* DRingAdapter.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DRingAdapter.mm; sourceTree = "<group>"; };
04399AA91D1C304300E99CD9 /* Ring-Bridging-Header.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "Ring-Bridging-Header.h"; sourceTree = "<group>"; };
04399AAA1D1C304300E99CD9 /* Utils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Utils.h; sourceTree = "<group>"; };
04399AAB1D1C304300E99CD9 /* Utils.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = Utils.mm; sourceTree = "<group>"; };
......@@ -295,6 +297,7 @@
02E1A0261DDE4C2E00D75B59 /* Services */ = {
isa = PBXGroup;
children = (
02B22E081DF7585F000358C9 /* DaemonService.swift */,
02B22DFE1DF755DB000358C9 /* AccountsService.swift */,
);
name = Services;
......@@ -376,7 +379,7 @@
043866341D22D04E00E06CE2 /* UI */,
0438662D1D22C87500E06CE2 /* ViewController */,
043866391D2307C000E06CE2 /* Extensions */,
04399AAF1D1C305600E99CD9 /* DRingAdaptator */,
04399AAF1D1C305600E99CD9 /* DRingAdapter */,
043999F61D1C2D9D00E99CD9 /* AppDelegate.swift */,
04399A021D1C2D9D00E99CD9 /* Assets.xcassets */,
04399A071D1C2D9D00E99CD9 /* Info.plist */,
......@@ -474,18 +477,18 @@
name = SYS_DEPS;
sourceTree = "<group>";
};
04399AAF1D1C305600E99CD9 /* DRingAdaptator */ = {
04399AAF1D1C305600E99CD9 /* DRingAdapter */ = {
isa = PBXGroup;
children = (
04399AA91D1C304300E99CD9 /* Ring-Bridging-Header.h */,
04399AA51D1C304300E99CD9 /* ConfigurationManagerAdaptator.h */,
04399AA61D1C304300E99CD9 /* ConfigurationManagerAdaptator.mm */,
04399AA71D1C304300E99CD9 /* DRingAdaptator.h */,
04399AA81D1C304300E99CD9 /* DRingAdaptator.mm */,
04399AA71D1C304300E99CD9 /* DRingAdapter.h */,
04399AA81D1C304300E99CD9 /* DRingAdapter.mm */,
04399AAA1D1C304300E99CD9 /* Utils.h */,
04399AAB1D1C304300E99CD9 /* Utils.mm */,
);
name = DRingAdaptator;
name = DRingAdapter;
sourceTree = "<group>";
};
/* End PBXGroup section */
......@@ -626,6 +629,7 @@
files = (
02E1A0251DDE4ABA00D75B59 /* BoolStringExtension.swift in Sources */,
04399AAC1D1C304300E99CD9 /* ConfigurationManagerAdaptator.mm in Sources */,
02B22E091DF7585F000358C9 /* DaemonService.swift in Sources */,
02B22E011DF755E5000358C9 /* MainTabBarViewController.swift in Sources */,
043999F71D1C2D9D00E99CD9 /* AppDelegate.swift in Sources */,
02B22DFC1DF755BB000358C9 /* AccountModel.swift in Sources */,
......@@ -636,7 +640,7 @@
0438663B1D2313B700E06CE2 /* AccountDetailsViewController.swift in Sources */,
043866361D22D06500E06CE2 /* AccountTableViewCell.swift in Sources */,
02B22E051DF75605000358C9 /* NotificationNames.swift in Sources */,
04399AAD1D1C304300E99CD9 /* DRingAdaptator.mm in Sources */,
04399AAD1D1C304300E99CD9 /* DRingAdapter.mm in Sources */,
02B22DFF1DF755DB000358C9 /* AccountsService.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
......
......@@ -2,6 +2,7 @@
* Copyright (C) 2016 Savoir-faire Linux Inc.
*
* Author: Edric Ladent-Milaret <edric.ladent-milaret@savoirfairelinux.com>
* Author: Romain Bertozzi <romain.bertozzi@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -25,22 +26,13 @@ import CoreData
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
let dRingAdapt = DRingAdaptator()
let daemonService = DaemonService.init(dRingAdaptor: DRingAdapter())
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
if (dRingAdapt.initDaemon() == true) {
if (dRingAdapt.startDaemon() == true) {
Timer.scheduledTimer(timeInterval: 0.05, target: self, selector: #selector(AppDelegate.pollFunction), userInfo: nil, repeats: true)
AccountsService.sharedInstance.reload()
}
}
self.startDaemon()
return true
}
func pollFunction() {
self.dRingAdapt.pollEvents()
}
func applicationWillResignActive(_ application: UIApplication) {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
......@@ -61,7 +53,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
func applicationWillTerminate(_ application: UIApplication) {
self.saveContext()
self.dRingAdapt.fini()
self.stopDaemon()
}
// MARK: - Core Data stack
......@@ -127,5 +119,29 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
}
}
// MARK: - Ring Daemon
fileprivate func startDaemon() {
do {
try self.daemonService.startDaemon()
} catch StartDaemonError.InitializationFailure {
print("Daemon failed to initialize.")
} catch StartDaemonError.StartFailure {
print("Daemon failed to start.")
} catch StartDaemonError.DaemonAlreadyRunning {
print("Daemon already running.")
} catch {
print("Unknown error in Daemon start.")
}
}
fileprivate func stopDaemon() {
do {
try self.daemonService.stopDaemon()
} catch StopDaemonError.DaemonNotRunning {
print("Daemon failed to stop because it was not already running.")
} catch {
print("Unknown error in Daemon stop.")
}
}
}
......@@ -21,7 +21,7 @@
#import <Foundation/Foundation.h>
@interface DRingAdaptator : NSObject
@interface DRingAdapter : NSObject
- (BOOL)initDaemon;
- (BOOL)startDaemon;
- (void)fini;
......
......@@ -19,11 +19,11 @@
* USA.
*/
#import "DRingAdaptator.h"
#import "DRingAdapter.h"
#import "dring/dring.h"
@implementation DRingAdaptator
@implementation DRingAdapter
- (BOOL)initDaemon {
int flag = DRing::DRING_FLAG_CONSOLE_LOG | DRing::DRING_FLAG_DEBUG;
......
......@@ -25,4 +25,4 @@
//
#import "ConfigurationManagerAdaptator.h"
#import "DRingAdaptator.h"
\ No newline at end of file
#import "DRingAdapter.h"
/*
* Copyright (C) 2016 Savoir-faire Linux Inc.
*
* Author: Romain Bertozzi <romain.bertozzi@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
import Foundation
/**
Errors that can be thrown when trying to start the daemon:
- DaemonAlreadyRunning: the daemon is already running.
- InitializationFailure: the daemon failed to initialiaze.
- StartFailure: the daemon failed to start.
*/
enum StartDaemonError: Error {
case DaemonAlreadyRunning
case InitializationFailure
case StartFailure
}
/**
Errors that can be thrown when trying to stop the daemon:
- DaemonNotRunning: the daemon is not running and can not be stopped.
*/
enum StopDaemonError: Error {
case DaemonNotRunning
}
/**
A service managing the daemon main features and lifecycle.
Its responsabilities:
- start the deamon
- stop the daemon
- orchestrate the poll events calls of the deamon
Its callbacks:
- does not currently expose any signal or callback of any kind.
*/
class DaemonService {
// MARK: Private members
/// Indicates whether the daemon is started or not.
fileprivate(set) internal var daemonStarted = false
/// The DRingAdaptor making the c++ bridge between the deamon and the App Swift source code.
fileprivate let dRingAdaptor: DRingAdapter
/// The time interval separating each poll.
fileprivate let pollingTimeInterval = 0.05
/// The timer scheduling the calls to the poll method.
fileprivate var pollingTimer: Timer?
// MARK: Initialization
init(dRingAdaptor: DRingAdapter) {
self.dRingAdaptor = dRingAdaptor
}
// MARK: Public API
/**
Starts the Ring daemon.
- Throws: StartDaemonError
*/
func startDaemon() throws {
guard !self.daemonStarted else {
throw StartDaemonError.DaemonAlreadyRunning
}
print("Starting daemon...")
if self.dRingAdaptor.initDaemon() {
print("Daemon initialized.")
if self.dRingAdaptor.startDaemon() {
self.startRingServicePolling()
self.daemonStarted = true
print("Daemon started.")
}
else {
throw StartDaemonError.StartFailure
}
}
else {
throw StartDaemonError.InitializationFailure
}
}
/**
Stops the Ring daemon.
- Throws: StopDaemonError
*/
func stopDaemon() throws {
guard self.daemonStarted else {
throw StopDaemonError.DaemonNotRunning
}
print("Stopping daemon...")
self.pollingTimer?.invalidate()
self.dRingAdaptor.fini()
self.daemonStarted = false
print("Daemon stopped.")
}
// MARK: Private Core
/**
Initiates the timer scheduling the calls to the daemon poll event method. It then starts it.
*/
fileprivate func startRingServicePolling() {
self.pollingTimer = Timer.scheduledTimer(timeInterval: pollingTimeInterval,
target: self,
selector: #selector(self.pollFunction),
userInfo: nil,
repeats: true)
}
/**
Performs the call to the daemon pollEvents method each time the pollingTimer decides to.
This method must be @objc exposed to be called by the timer.
*/
@objc fileprivate func pollFunction() {
self.dRingAdaptor.pollEvents()
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment