blob: 6b6c75e97ed8a480787e50cbc3a06b674a4a3480 [file] [log] [blame]
Alexander Afanasyev14b09482013-10-11 18:24:45 +02001/* -*- Mode: obj; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
Alexander Afanasyev88f0b3a2013-09-24 23:52:08 -07002/*
3 * @copyright See LICENCE for copyright and license information.
4 *
5 * @author Alexander Afanasyev <alexander.afanasyev@ucla.edu>
6 * @author Ilya Moiseenko <iliamo@ucla.edu>
7 */
8
Alexander Afanasyev2beff7f2013-09-27 17:50:36 -07009#include "config.h"
Alexander Afanasyev88f0b3a2013-09-24 23:52:08 -070010#import "menu-delegate.h"
Alexander Afanasyev6cacb972013-10-03 23:39:06 -070011#import "ndnd-status-operation.h"
Ilya Moiseenko0c9ab7c2013-10-29 15:08:23 -070012#import "tight-menu-item-view.h"
Ilya Moiseenko2dffcf52013-09-27 15:08:04 -070013
Alexander Afanasyev88f0b3a2013-09-24 23:52:08 -070014@implementation MenuDelegate
15
Alexander Afanasyev506d0ab2013-10-29 19:18:10 -070016@synthesize interestSent;
17@synthesize interestRecv;
18@synthesize dataSent;
19@synthesize dataRecv;
20
Alexander Afanasyev6cacb972013-10-03 23:39:06 -070021-(id)init
22{
23 if (![super init]) {
24 return nil;
25 }
26
Alexander Afanasyev506d0ab2013-10-29 19:18:10 -070027 interestSent = @"N/A";
28 interestRecv = @"N/A";
29 dataSent = @"N/A";
30 dataRecv = @"N/A";
31
Alexander Afanasyevb9024d12013-10-14 18:10:18 +030032 m_autoconfInProgress = false;
Alexander Afanasyev6cacb972013-10-03 23:39:06 -070033 m_operationQueue = [[NSOperationQueue alloc] init];
34 return self;
35}
36
Alexander Afanasyev88f0b3a2013-09-24 23:52:08 -070037- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
38{
Alexander Afanasyev1d794ce2013-10-22 12:48:30 -070039 // Register the preference defaults early.
40 NSDictionary *appDefaults =
41 [NSDictionary dictionaryWithObjectsAndKeys:
42 [NSNumber numberWithBool:YES], @"allowSoftwareUpdates",
43 [NSNumber numberWithBool:YES], @"enableHubDiscovery",
44 [NSNumber numberWithBool:NO], @"shutdownNdndOnExit",
45 nil
46 ];
47 [[NSUserDefaults standardUserDefaults] registerDefaults:appDefaults];
48
49 // Other initialization...
50
Alexander Afanasyev6cacb972013-10-03 23:39:06 -070051 m_daemonStarted = false;
Alexander Afanasyev6cacb972013-10-03 23:39:06 -070052
53 NSBundle *bundle = [NSBundle bundleForClass:[self class]];
54 m_connectedIcon = [[NSImage alloc] initWithContentsOfFile:[bundle pathForResource:@"FlatConnected" ofType:@"png"]];
55 m_disconnectedIcon = [[NSImage alloc] initWithContentsOfFile:[bundle pathForResource:@"FlatDisconnected" ofType:@"png"]];
56 m_statusXslt = [NSData dataWithContentsOfFile:[bundle pathForResource:@"status" ofType:@"xslt"]];
Ilya Moiseenkob4aca052013-10-06 15:10:19 -070057 m_statusToFibXslt = [NSData dataWithContentsOfFile:[bundle pathForResource:@"status-to-fib" ofType:@"xslt"]];
Ilya Moiseenko6d4086c2013-09-27 16:56:02 -070058
Alexander Afanasyevb9024d12013-10-14 18:10:18 +030059 [NSTimer scheduledTimerWithTimeInterval: 1.0
60 target: self
61 selector:@selector(onTick:)
62 userInfo: nil
63 repeats:YES];
Alexander Afanasyev4e1c7e92013-10-11 18:25:09 +020064 [self updateStatus];
Alexander Afanasyev17922872013-10-15 11:45:58 +030065
66 m_systemEvents = [[SystemEvents alloc] init];
67}
68
69- (void)applicationWillTerminate:(NSNotification *)aNotification
70{
71 [m_systemEvents disable];
Alexander Afanasyev88f0b3a2013-09-24 23:52:08 -070072}
73
Alexander Afanasyev88f0b3a2013-09-24 23:52:08 -070074-(void)awakeFromNib
75{
76 statusItem = [[NSStatusBar systemStatusBar] statusItemWithLength:NSVariableStatusItemLength];
Alexander Afanasyev88f0b3a2013-09-24 23:52:08 -070077 [statusItem setMenu:statusMenu];
Ilya Moiseenko350b9b52013-09-25 16:38:41 -070078 [statusItem setToolTip:@"NDN Control Center"];
79 [statusItem setEnabled:YES];
Alexander Afanasyev88f0b3a2013-09-24 23:52:08 -070080 [statusItem setHighlightMode:YES];
Ilya Moiseenko350b9b52013-09-25 16:38:41 -070081 //[statusItem setTarget:self];
82
Ilya Moiseenko350b9b52013-09-25 16:38:41 -070083 [statusItem setTitle:@""];
Alexander Afanasyev6cacb972013-10-03 23:39:06 -070084 [statusItem setImage:m_disconnectedIcon];
Ilya Moiseenko01264322013-09-26 15:34:21 -070085
Ilya Moiseenko0c9ab7c2013-10-29 15:08:23 -070086 float menuItemHeight = 20;
87
88 NSRect viewRect = NSMakeRect(0, 0, /* width autoresizes */ 1, menuItemHeight);
89 connectionStatusView = [[TightMenuItemView alloc] initWithFrame:viewRect];
90 connectionStatusView.autoresizingMask = NSViewWidthSizable;
91
92 [connectionStatus setView:connectionStatusView];
Ilya Moiseenko01264322013-09-26 15:34:21 -070093 [connectionStatus setTarget:self];
Alexander Afanasyev6cacb972013-10-03 23:39:06 -070094
Ilya Moiseenko01264322013-09-26 15:34:21 -070095 [daemonStatus setView: daemonStatusView];
96 [daemonStatus setTarget:self];
Ilya Moiseenkoa10ef8d2013-09-25 17:23:05 -070097}
98
Ilya Moiseenko350b9b52013-09-25 16:38:41 -070099-(IBAction)openDaemonStatus:(id)sender
100{
Ilya Moiseenko350b9b52013-09-25 16:38:41 -0700101}
102
Ilya Moiseenkoe7058e72013-10-02 15:56:45 -0700103-(IBAction)showExitConfirmationWindow:(id)sender
Ilya Moiseenko350b9b52013-09-25 16:38:41 -0700104{
Alexander Afanasyev1d794ce2013-10-22 12:48:30 -0700105 if ([[NSUserDefaults standardUserDefaults] boolForKey:@"shutdownNdndOnExit"]) {
Alexander Afanasyev6cacb972013-10-03 23:39:06 -0700106 [m_operationQueue cancelAllOperations];
Alexander Afanasyev4e1c7e92013-10-11 18:25:09 +0200107
108 [m_operationQueue addOperationWithBlock:^{
109 NSTask *task = [[NSTask alloc] init];
110 [task setLaunchPath: @NDND_STOP_COMMAND];
111 [task launch];
112 [task waitUntilExit];
113 }];
114
115 [m_operationQueue waitUntilAllOperationsAreFinished];
Alexander Afanasyev6cacb972013-10-03 23:39:06 -0700116 [NSApp terminate:self];
Alexander Afanasyev1d794ce2013-10-22 12:48:30 -0700117 }
118 else {
119 NSAlert *alert = [[NSAlert alloc] init];
120 [alert addButtonWithTitle:@"Yes"];
121 [alert addButtonWithTitle:@"No"];
122 [alert addButtonWithTitle:@"Cancel"];
123 [alert setMessageText:@"Shutdown NDN daemon as well?"];
124 [alert setInformativeText:@"All NDN operations will be become unavailable."];
125 [alert setAlertStyle:NSCriticalAlertStyle];
126 // [alert setShowsSuppressionButton: YES];
127
128 NSInteger res = [alert runModal];
129 if (res == NSAlertFirstButtonReturn) {
130 // "YES" stop ndnd
131 [m_operationQueue cancelAllOperations];
132
133 [m_operationQueue addOperationWithBlock:^{
134 NSTask *task = [[NSTask alloc] init];
135 [task setLaunchPath: @NDND_STOP_COMMAND];
136 [task launch];
137 [task waitUntilExit];
138 }];
139
140 [m_operationQueue waitUntilAllOperationsAreFinished];
141 [NSApp terminate:self];
142 } else if (res == NSAlertSecondButtonReturn) {
143 // "NO" terminate app but keep ndnd running
144 [m_operationQueue cancelAllOperations];
145 [NSApp terminate:self];
146 }
Alexander Afanasyev6cacb972013-10-03 23:39:06 -0700147 }
Alexander Afanasyev88f0b3a2013-09-24 23:52:08 -0700148}
149
Ilya Moiseenko6d4086c2013-09-27 16:56:02 -0700150-(void)onTick:(NSTimer *)timer
151{
Alexander Afanasyev4e1c7e92013-10-11 18:25:09 +0200152 [self updateStatus];
153}
154
155-(void)updateStatus
156{
157 NSOperation *operation = [[NdndStatusOperation alloc] initWithDelegate:self];
158 [m_operationQueue addOperation:operation];
159}
160
161-(void)updateStatusWithDependency:(NSOperation*)dependency
162{
163 NSOperation *operation = [[NdndStatusOperation alloc] initWithDelegate:self];
164 [operation addDependency:dependency];
165
166 [m_operationQueue addOperation:dependency];
167 [m_operationQueue addOperation:operation];
Alexander Afanasyev6cacb972013-10-03 23:39:06 -0700168}
169
170- (void)statusUpdated:(NSXMLDocument*)document
171{
172 if (!m_daemonStarted) {
173 m_daemonStarted = true;
Ilya Moiseenko0c9ab7c2013-10-29 15:08:23 -0700174 [connectionStatusView setStatus:@"Active"];
Ilya Moiseenko6d4086c2013-09-27 16:56:02 -0700175
Alexander Afanasyev6cacb972013-10-03 23:39:06 -0700176 [statusItem setImage:m_connectedIcon];
Ilya Moiseenko6d4086c2013-09-27 16:56:02 -0700177 }
Alexander Afanasyev6cacb972013-10-03 23:39:06 -0700178
Ilya Moiseenkob4aca052013-10-06 15:10:19 -0700179 NSXMLDocument *statusXml = [document objectByApplyingXSLT:m_statusXslt
180 arguments:nil
181 error:nil];
Alexander Afanasyev6cacb972013-10-03 23:39:06 -0700182
Ilya Moiseenkob4aca052013-10-06 15:10:19 -0700183 NSXMLDocument *statusFibXml = [document objectByApplyingXSLT:m_statusToFibXslt
184 arguments:nil
185 error:nil];
Alexander Afanasyev506d0ab2013-10-29 19:18:10 -0700186
187 NSXMLNode *element = [[statusXml rootElement] childAtIndex:0]; //data
188 [self setDataRecv:[[element childAtIndex:0] stringValue]];
189 [self setDataSent:[[element childAtIndex:1] stringValue]];
190
191 element = [[statusXml rootElement] childAtIndex:1]; //interests
192 [self setInterestRecv:[[element childAtIndex:0] stringValue]];
193 [self setInterestSent:[[element childAtIndex:1] stringValue]];
Ilya Moiseenkob4aca052013-10-06 15:10:19 -0700194
195 [preferencesDelegate updateFibStatus:statusFibXml];
Alexander Afanasyevb9024d12013-10-14 18:10:18 +0300196
Alexander Afanasyev1d794ce2013-10-22 12:48:30 -0700197 if ([[NSUserDefaults standardUserDefaults] boolForKey:@"enableHubDiscovery"]) {
198 NSArray *autoconf = [[statusFibXml rootElement] nodesForXPath:@"//fib/prefix[text()='ndn:/autoconf-route']" error:nil];
199 if ([autoconf count] == 0)
200 {
201 [self restartDaemon:nil];
202 }
203 }
Ilya Moiseenko6d4086c2013-09-27 16:56:02 -0700204}
205
Alexander Afanasyev6cacb972013-10-03 23:39:06 -0700206- (void)statusUnavailable:(id)none
Ilya Moiseenkoe7058e72013-10-02 15:56:45 -0700207{
Alexander Afanasyev6cacb972013-10-03 23:39:06 -0700208 // try start ndnd if it is not started yet
209 if (m_daemonStarted) {
210 m_daemonStarted = false;
211
Ilya Moiseenko0c9ab7c2013-10-29 15:08:23 -0700212 [connectionStatusView setStatus:@"Starting..."];
Alexander Afanasyev6cacb972013-10-03 23:39:06 -0700213
214 [statusItem setImage:m_disconnectedIcon];
215 }
Ilya Moiseenkob4aca052013-10-06 15:10:19 -0700216
Alexander Afanasyev506d0ab2013-10-29 19:18:10 -0700217 [self setInterestSent:@"N/A"];
218 [self setInterestRecv:@"N/A"];
219 [self setDataSent:@"N/A"];
220 [self setDataRecv:@"N/A"];
221
Ilya Moiseenkob4aca052013-10-06 15:10:19 -0700222 [preferencesDelegate updateFibStatus:nil];
223
Alexander Afanasyevb9024d12013-10-14 18:10:18 +0300224 m_autoconfInProgress = true;
225
226 NSOperation *startOp = [NSBlockOperation blockOperationWithBlock:^{
Alexander Afanasyev6cacb972013-10-03 23:39:06 -0700227 NSTask *task = [[NSTask alloc] init];
228 [task setLaunchPath: @NDND_START_COMMAND];
229 [task launch];
230 }];
Alexander Afanasyevb9024d12013-10-14 18:10:18 +0300231
Alexander Afanasyev1d794ce2013-10-22 12:48:30 -0700232 if ([[NSUserDefaults standardUserDefaults] boolForKey:@"enableHubDiscovery"]) {
233 NSOperation *autoconfOp = [NSBlockOperation blockOperationWithBlock:^{
234 NSTask *task = [[NSTask alloc] init];
235 [task setLaunchPath: @NDND_AUTOCONFIG_COMMAND];
236 [task launch];
237 [task waitUntilExit];
Alexander Afanasyevb9024d12013-10-14 18:10:18 +0300238
Alexander Afanasyev1d794ce2013-10-22 12:48:30 -0700239 m_autoconfInProgress = false;
240 }];
Alexander Afanasyevb9024d12013-10-14 18:10:18 +0300241
Alexander Afanasyev1d794ce2013-10-22 12:48:30 -0700242 [autoconfOp addDependency:startOp];
243 [m_operationQueue addOperation:autoconfOp];
244 }
Alexander Afanasyevb9024d12013-10-14 18:10:18 +0300245
246 [m_operationQueue addOperation:startOp];
Alexander Afanasyevb9024d12013-10-14 18:10:18 +0300247}
248
249-(void)restartDaemon:(id)none
250{
Alexander Afanasyev1d794ce2013-10-22 12:48:30 -0700251 if (![[NSUserDefaults standardUserDefaults] boolForKey:@"enableHubDiscovery"])
252 return;
253
Alexander Afanasyevb9024d12013-10-14 18:10:18 +0300254 if (m_autoconfInProgress)
255 return;
256
Alexander Afanasyev17922872013-10-15 11:45:58 +0300257 NSLog (@"No automatically detected route configured, trying to get one");
258
Alexander Afanasyevb9024d12013-10-14 18:10:18 +0300259 m_autoconfInProgress = true;
260 [m_operationQueue addOperationWithBlock:^{
261 NSTask *task = [[NSTask alloc] init];
262 [task setLaunchPath: @NDND_AUTOCONFIG_COMMAND];
263 [task launch];
264 [task waitUntilExit];
265
266 m_autoconfInProgress = false;
267 }];
Ilya Moiseenkoe7058e72013-10-02 15:56:45 -0700268}
269
Alexander Afanasyev88f0b3a2013-09-24 23:52:08 -0700270@end