diff --git a/launchers/macosx/I2PLauncher/SwiftMainDelegate.swift b/launchers/macosx/I2PLauncher/SwiftMainDelegate.swift
index 9415a698b8..b5b60bf1c1 100644
--- a/launchers/macosx/I2PLauncher/SwiftMainDelegate.swift
+++ b/launchers/macosx/I2PLauncher/SwiftMainDelegate.swift
@@ -13,18 +13,19 @@ import Cocoa
//let statusItem = NSStatusBar.system().statusItem(withLength: NSSquareStatusItemLength )
let statusBarController = StatusBarController()
- let javaDetector = DetectJava()
+ static let javaDetector = DetectJava()
static let objCBridge = SBridge()
override init() {
super.init()
-
- self.javaDetector.findIt()
- if (!javaDetector.isJavaFound()) {
- print("Could not find java....")
- terminate("No java..")
+ if (!SwiftMainDelegate.javaDetector.isJavaFound()) {
+ SwiftMainDelegate.javaDetector.findIt()
+ if (!SwiftMainDelegate.javaDetector.isJavaFound()) {
+ print("Could not find java....")
+ terminate("No java..")
+ }
}
- let javaBinPath = self.javaDetector.javaHome
+ let javaBinPath = SwiftMainDelegate.javaDetector.javaHome
RouterProcessStatus.knownJavaBinPath = javaBinPath
print("Found java home = ", javaBinPath)
@@ -77,8 +78,6 @@ import Cocoa
var i2pPath = NSHomeDirectory()
i2pPath += "/Library/I2P"
- //let javaBinPath = self.javaDetector.javaHome.replace(target: " ", withString: "\\ ")
-
let fileManager = FileManager()
var ok = ObjCBool(true)
let doesI2PDirExists = fileManager.fileExists(atPath: i2pPath, isDirectory: &ok)
diff --git a/launchers/macosx/I2PLauncher/routermgmt/DetectJava.swift b/launchers/macosx/I2PLauncher/routermgmt/DetectJava.swift
index f70d20f8de..186318e092 100644
--- a/launchers/macosx/I2PLauncher/routermgmt/DetectJava.swift
+++ b/launchers/macosx/I2PLauncher/routermgmt/DetectJava.swift
@@ -10,9 +10,9 @@ import Foundation
@objc class DetectJava : NSObject {
- var hasJRE : Bool = false
- var userWantJRE : Bool = false
- var userAcceptOracleEULA : Bool = false
+ static var hasJRE : Bool = false
+ static var userWantJRE : Bool = false
+ static var userAcceptOracleEULA : Bool = false
override init() {
@@ -29,8 +29,9 @@ import Foundation
//Called after the change
didSet{
- hasJRE = true
- print("DetectJava.javaHome did change from "+oldValue+" to "+self.javaHome)
+ DetectJava.hasJRE = true
+ self.javaHome = self.javaHome.replace(target: "\n", withString: "").replace(target: "Internet Plug-Ins", withString: "Internet\\ Plug-Ins")
+ print("DetectJava.javaHome did change to "+self.javaHome)
}
};
private var testedEnv : Bool = false
@@ -50,25 +51,28 @@ import Foundation
*
**/
@objc func findIt() {
+ if (DetectJava.hasJRE) {
+ return
+ }
print("Start with checking environment variable")
self.checkJavaEnvironmentVariable()
if !(self.javaHome.isEmpty) {
RouterProcessStatus.knownJavaBinPath = Optional.some(self.javaHome)
- hasJRE = true
+ DetectJava.hasJRE = true
return
}
print("Checking with the java_home util")
self.runJavaHomeCmd()
if !(self.javaHome.isEmpty) {
RouterProcessStatus.knownJavaBinPath = Optional.some(self.javaHome)
- hasJRE = true
+ DetectJava.hasJRE = true
return
}
print("Checking default JRE install path")
self.checkDefaultJREPath()
if !(self.javaHome.isEmpty) {
RouterProcessStatus.knownJavaBinPath = Optional.some(self.javaHome)
- hasJRE = true
+ DetectJava.hasJRE = true
return
}
}
diff --git a/launchers/macosx/I2PLauncher/routermgmt/RouterProcessStatus.swift b/launchers/macosx/I2PLauncher/routermgmt/RouterProcessStatus.swift
index 7fe785bfc5..0ee054ae40 100644
--- a/launchers/macosx/I2PLauncher/routermgmt/RouterProcessStatus.swift
+++ b/launchers/macosx/I2PLauncher/routermgmt/RouterProcessStatus.swift
@@ -26,7 +26,7 @@ import AppKit
}
@objc func getRouterIsRunning() -> Bool {
- if (RouterProcessStatus.isRouterRunning == Optional.none) {
+ if (RouterProcessStatus.isRouterRunning) {
return false;
} else {
let running: Bool = RouterProcessStatus.isRouterRunning
diff --git a/launchers/macosx/I2PLauncher/userinterface/PopoverViewController.swift b/launchers/macosx/I2PLauncher/userinterface/PopoverViewController.swift
index f81651abff..4980326c30 100644
--- a/launchers/macosx/I2PLauncher/userinterface/PopoverViewController.swift
+++ b/launchers/macosx/I2PLauncher/userinterface/PopoverViewController.swift
@@ -60,7 +60,7 @@ class PopoverViewController: NSViewController {
override func viewWillDraw() {
super.viewWillDraw()
- if (RouterStatusView.instance == Optional.none) {
+ if (RouterStatusView.instance != nil) {
RouterStatusView.instance = self
}
self.setRouterStatusLabelText()
@@ -78,16 +78,13 @@ class PopoverViewController: NSViewController {
routerStartStopButton?.target = self
quickControlView?.needsDisplay = true
- if (RouterProcessStatus.routerVersion == Optional.none) {
- routerVersionLabel?.cell?.stringValue = "Router version: Still unknown"
- // trigger a read to ensure values
- let tmp = SwiftMainDelegate()
- tmp.findInstalledI2PVersion()
+ if let version = RouterProcessStatus.routerVersion {
+ routerVersionLabel?.cell?.stringValue = "Router version: " + version
} else {
- routerVersionLabel?.cell?.stringValue = "Router version: " + RouterProcessStatus.routerVersion!
+ routerVersionLabel?.cell?.stringValue = "Router version: Still unknown"
}
- if (RouterProcessStatus.routerStartedAt != Optional.none) {
- routerUptimeLabel?.cell?.stringValue = "Router has runned for " + DateTimeUtils.timeAgoSinceDate(date: NSDate(date: RouterProcessStatus.routerStartedAt!), numericDates: false)
+ if let routerStartTime = RouterProcessStatus.routerStartedAt {
+ routerUptimeLabel?.cell?.stringValue = "Router has runned for " + DateTimeUtils.timeAgoSinceDate(date: NSDate(date: routerStartTime), numericDates: false)
}
}
diff --git a/launchers/macosx/Info.plist b/launchers/macosx/Info.plist
index b63c2dbba9..f07062c055 100644
--- a/launchers/macosx/Info.plist
+++ b/launchers/macosx/Info.plist
@@ -9,7 +9,7 @@
NSHumanReadableCopyright
Public Domain
CFBundleGetInfoString
- 0.9.35-experimental
+ 0.9.36-experimental
CFBundleIconFile
images/AppIcon.icns
CFBundleIdentifier
diff --git a/launchers/macosx/RouterTask.h b/launchers/macosx/RouterTask.h
index e81cd924c7..3b8e7db184 100644
--- a/launchers/macosx/RouterTask.h
+++ b/launchers/macosx/RouterTask.h
@@ -16,7 +16,21 @@ class JavaRunner;
typedef std::function fp_t;
typedef std::function fp_proc_t;
+const std::vector defaultStartupFlags {
+ @"-Xmx512M",
+ @"-Xms128m",
+ @"-Djava.awt.headless=true",
+ @"-Dwrapper.logfile=/tmp/router.log",
+ @"-Dwrapper.logfile.loglevel=DEBUG",
+ @"-Dwrapper.java.pidfile=/tmp/routerjvm.pid",
+ @"-Dwrapper.console.loglevel=DEBUG"
+};
+const std::vector defaultFlagsForExtractorJob {
+ "-Xmx512M",
+ "-Xms128m",
+ "-Djava.awt.headless=true"
+};
/**
*
@@ -30,9 +44,6 @@ public:
JavaRunner(std::string& javaBin, std::string& arguments, std::string& i2pBaseDir, const fp_proc_t& executingFn, const fp_t& cb);
~JavaRunner() = default;
- static const std::vector defaultStartupFlags;
- static const std::vector defaultFlagsForExtractorJob;
-
void requestRouterShutdown();
std::future execute();
diff --git a/launchers/macosx/RouterTask.mm b/launchers/macosx/RouterTask.mm
index 80a7a2956f..51b955d50d 100644
--- a/launchers/macosx/RouterTask.mm
+++ b/launchers/macosx/RouterTask.mm
@@ -112,23 +112,6 @@
#ifdef __cplusplus
-
-const std::vector JavaRunner::defaultStartupFlags {
- @"-Xmx512M",
- @"-Xms128m",
- @"-Djava.awt.headless=true",
- @"-Dwrapper.logfile=/tmp/router.log",
- @"-Dwrapper.logfile.loglevel=DEBUG",
- @"-Dwrapper.java.pidfile=/tmp/routerjvm.pid",
- @"-Dwrapper.console.loglevel=DEBUG"
-};
-
-const std::vector JavaRunner::defaultFlagsForExtractorJob {
- "-Xmx512M",
- "-Xms128m",
- "-Djava.awt.headless=true"
-};
-
JavaRunner::JavaRunner(std::string& javaBin, std::string& arguments, std::string& i2pBaseDir, const fp_proc_t& execFn, const fp_t& cb)
: javaBinaryPath(javaBin), javaRouterArgs(arguments), _i2pBaseDir(i2pBaseDir), executingFn(execFn), exitCallbackFn(cb)
{
diff --git a/launchers/macosx/include/strutil.hpp b/launchers/macosx/include/strutil.hpp
index de60853c58..ab52a1c01c 100644
--- a/launchers/macosx/include/strutil.hpp
+++ b/launchers/macosx/include/strutil.hpp
@@ -98,10 +98,10 @@ static inline std::string trim_copy(std::string s) {
return s;
}
-#ifdef CPP17
+#if __cplusplus > 201402L
-using std::experimental::optional;
+using std::optional;
// Use CFStringRef instead of NSString*, otherwise disable ARC
inline optional optionalString(bool val) {
diff --git a/launchers/macosx/main.mm b/launchers/macosx/main.mm
index 2456ccd891..ba21e50d7e 100644
--- a/launchers/macosx/main.mm
+++ b/launchers/macosx/main.mm
@@ -33,46 +33,16 @@
#include "JavaHelper.h"
#include "include/fn.h"
#include "include/portcheck.h"
+#import "SBridge.h"
#ifdef __cplusplus
-#import "SBridge.h"
+#include
#include "include/subprocess.hpp"
#include "include/strutil.hpp"
using namespace subprocess;
-JvmListSharedPtr gRawJvmList = nullptr;
-
-maybeAnRouterRunner getGlobalRouterObject()
-{
- std::lock_guard lock(globalRouterStatusMutex);
- return globalRouterStatus; // Remember this might be nullptr now.
-}
-
-void setGlobalRouterObject(I2PRouterTask* newRouter)
-{
- std::lock_guard lock(globalRouterStatusMutex);
- globalRouterStatus = newRouter;
-}
-
-
-pthread_mutex_t mutex;
-
-bool getGlobalRouterIsRunning()
-{
- pthread_mutex_lock(&mutex);
- bool current = isRuterRunning;
- pthread_mutex_unlock(&mutex);
- return current;
-}
-void setGlobalRouterIsRunning(bool running)
-{
- pthread_mutex_lock(&mutex);
- isRuterRunning = running;
- pthread_mutex_unlock(&mutex);
-}
-
#endif
#define debug(format, ...) CFShow([NSString stringWithFormat:format, ## __VA_ARGS__]);
@@ -90,6 +60,12 @@ void setGlobalRouterIsRunning(bool running)
- (void) awakeFromNib {
}
+
+- (BOOL)userNotificationCenter:(NSUserNotificationCenter *)center
+ shouldPresentNotification:(NSUserNotification *)notification {
+ return YES;
+}
+
#ifdef __cplusplus
- (void)extractI2PBaseDir:(void(^)(BOOL success, NSError *error))completion
@@ -125,7 +101,7 @@ void setGlobalRouterIsRunning(bool running)
// Create directory
mkdir(basePath.c_str(), S_IRUSR | S_IWUSR | S_IXUSR);
- auto cli = JavaRunner::defaultFlagsForExtractorJob;
+ auto cli = defaultFlagsForExtractorJob;
setenv("I2PBASE", basePath.c_str(), true);
setenv("ZIPPATH", zippath.c_str(), true);
//setenv("DYLD_LIBRARY_PATH",".:/usr/lib:/lib:/usr/local/lib", true);
@@ -143,19 +119,8 @@ void setGlobalRouterIsRunning(bool running)
NSString* newString = [NSString stringWithFormat:@"file://%@", rs.getJavaHome];
NSURL *baseURL = [NSURL fileURLWithPath:newString];
- NSLog(@"MEEH URL PATH: %s", [baseURL fileSystemRepresentation]);
-
- auto charCli = map(cli, [](std::string str){ return str.c_str(); });
std::string execStr = std::string([rs.getJavaHome UTF8String]);
- // TODO: Cheap hack, make it better.
- replace(execStr, "Internet Plug-Ins", "Internet\\ Plug-Ins");
- replace(execStr, "\n", "");
- NSLog(@"Java path1 = %s", execStr.c_str());
- [rs setJavaHome: [NSString stringWithFormat:@"%s", execStr.c_str()]];
for_each(cli, [&execStr](std::string str){ execStr += std::string(" ") + str; });
-
- //execStr = replace(execStr, "\\\\ ", "\\ ");
- //NSLog(@"Java path2 = %s", execStr.c_str());
NSLog(@"Trying cmd: %@", [NSString stringWithUTF8String:execStr.c_str()]);
try {
@@ -197,15 +162,6 @@ void setGlobalRouterIsRunning(bool running)
}
-#endif
-
-- (BOOL)userNotificationCenter:(NSUserNotificationCenter *)center
- shouldPresentNotification:(NSUserNotification *)notification {
- return YES;
-}
-
-
-#ifdef __cplusplus
- (NSString *)userSelectJavaHome:(JvmListPtr)rawJvmList
{
@@ -227,33 +183,19 @@ void setGlobalRouterIsRunning(bool running)
return userResult;
}
-
-- (void)userChooseJavaHome {
- listAllJavaInstallsAvailable();
- std::shared_ptr appContext = std::shared_ptr( new JvmHomeContext() );
- for (auto item : *appContext->getJvmList()) {
- printf("JVM %s (Version: %s, Directory: %s)\n", item->JVMName.c_str(), item->JVMPlatformVersion.c_str(), item->JVMHomePath.c_str());
- }
- JvmListPtr rawJvmList = appContext->getJvmList();
- NSString * userJavaHome = [self userSelectJavaHome: rawJvmList];
- // TODO: Add logic so user can set preferred JVM
-}
-
-#endif
-
- (void)setApplicationDefaultPreferences {
auto defaultJVMHome = check_output({"/usr/libexec/java_home","-v",DEF_MIN_JVM_VER});
auto tmpStdStr = std::string(defaultJVMHome.buf.data());
trim(tmpStdStr);
auto cfDefaultHome = CFStringCreateWithCString(NULL, const_cast(tmpStdStr.c_str()), kCFStringEncodingUTF8);
- /*[self.userPreferences registerDefaults:@{
+ [self.userPreferences registerDefaults:@{
@"javaHome" : (NSString *)cfDefaultHome,
@"lastI2PVersion" : (NSString *)CFSTR(DEF_I2P_VERSION),
@"enableLogging": @YES,
@"enableVerboseLogging": @YES,
@"autoStartRouter": @YES,
@"i2pBaseDirectory": (NSString *)CFStringCreateWithCString(NULL, const_cast(getDefaultBaseDir().c_str()), kCFStringEncodingUTF8)
- }];*/
+ }];
if (self.enableVerboseLogging) NSLog(@"Default JVM home preference set to: %@", cfDefaultHome);
auto dict = [self.userPreferences dictionaryRepresentation];
@@ -263,53 +205,40 @@ void setGlobalRouterIsRunning(bool running)
CFPreferencesAppSynchronize(kCFPreferencesCurrentApplication);
if (self.enableVerboseLogging) NSLog(@"Default preferences stored!");
+#endif
}
+
+
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
// Init application here
self.swiftRuntime = [[SwiftMainDelegate alloc] init];
+ // This setup allows the application to send notifications
[[NSUserNotificationCenter defaultUserNotificationCenter] setDelegate:self];
+
+
// Start with user preferences
self.userPreferences = [NSUserDefaults standardUserDefaults];
[self setApplicationDefaultPreferences];
self.enableLogging = [self.userPreferences boolForKey:@"enableLogging"];
self.enableVerboseLogging = [self.userPreferences boolForKey:@"enableVerboseLogging"];
-
-
-#ifdef __cplusplus
- gRawJvmList = std::make_shared >(std::list());
-#endif
// In case we are unbundled, make us a proper UI application
[NSApp setActivationPolicy:NSApplicationActivationPolicyAccessory];
[NSApp activateIgnoringOtherApps:YES];
- // TODO: Also check for new installations from time to time.
-
+
#ifdef __cplusplus
- auto javaHomePref = [self.userPreferences stringForKey:@"javaHome"];
- if (self.enableVerboseLogging)
- {
- NSLog(@"Java home from preferences: %@", javaHomePref);
- }
+ //gRawJvmList = std::make_shared >(std::list());
- if (self.enableVerboseLogging)
- {
- NSString *appDomain = [[NSBundle mainBundle] bundleIdentifier];
- NSLog(@"Appdomain is: %@", appDomain);
- }
-
- NSLog(@"We should have started the statusbar object by now...");
RouterProcessStatus* routerStatus = [[RouterProcessStatus alloc] init];
-
std::string i2pBaseDir(getDefaultBaseDir());
-
- auto pref = self.userPreferences;
-
+ NSLog(@"i2pBaseDir = %s", i2pBaseDir.c_str());
bool shouldAutoStartRouter = false;
-
+
+ // TODO: Make the port a setting which defaults to 7657
if (port_check(7657) != 0)
{
NSLog(@"Seems i2p is already running - I will not start the router (port 7657 is in use..)");
@@ -324,44 +253,26 @@ void setGlobalRouterIsRunning(bool running)
if (self.enableVerboseLogging) NSLog(@"processinfo %@", [[NSProcessInfo processInfo] arguments]);
- auto getJavaBin = [&pref,&self]() -> std::string {
- // Get Java home
- /*NSString* val = @"";
- val = [pref stringForKey:@"javaHome"];
- if (val == NULL) val = @"";
- if (self.enableVerboseLogging) NSLog(@"Javahome: %@", val);
- auto javaHome = std::string([val UTF8String]);
- //trim(javaHome); // Trim to remove endline
- auto javaBin = std::string(javaHome);
- javaBin += "/bin/java"; // Append java binary to path.
- return javaBin;*/
- DetectJava *dt = [[DetectJava alloc] init];
- [dt findIt];
- if ([dt isJavaFound]) {
- return [dt.javaHome UTF8String];
- } else {
- throw new std::runtime_error("Java home fatal error");
- }
- };
-
NSBundle *launcherBundle = [NSBundle mainBundle];
- auto jarResPath = [launcherBundle pathForResource:@"launcher" ofType:@"jar"];
- NSLog(@"Trying to load launcher.jar from url = %@", jarResPath);
-
+ // Helper object to hold statefull path information
self.metaInfo = [[ExtractMetaInfo alloc] init];
- //self.metaInfo.i2pBase = [NSString stringWithUTF8String:i2pBaseDir.c_str()];
- self.metaInfo.javaBinary = [NSString stringWithUTF8String:getJavaBin().c_str()];
+ self.metaInfo.i2pBase = [NSString stringWithUTF8String:i2pBaseDir.c_str()];
+ self.metaInfo.javaBinary = [routerStatus getJavaHome];
self.metaInfo.jarFile = [launcherBundle pathForResource:@"launcher" ofType:@"jar"];
self.metaInfo.zipFile = [launcherBundle pathForResource:@"base" ofType:@"zip"];
std::string basearg("-Di2p.dir.base=");
- //basearg += i2pBaseDir;
+ basearg += i2pBaseDir;
std::string jarfile("-cp ");
jarfile += [self.metaInfo.zipFile UTF8String];
+ auto sBridge = [[SBridge alloc] init];
+
+ // Initialize the Swift environment (the UI components)
+ [self.swiftRuntime applicationDidFinishLaunching];
struct stat sb;
if ( !(stat(i2pBaseDir.c_str(), &sb) == 0 && S_ISDIR(sb.st_mode)) )
@@ -369,17 +280,25 @@ void setGlobalRouterIsRunning(bool running)
// I2P is not extracted.
if (self.enableVerboseLogging) NSLog(@"I2P Directory don't exists!");
+ // Might be hard to read if you're not used to Objective-C
+ // But this is a "function call" that contains a "callback function"
[self extractI2PBaseDir:^(BOOL success, NSError *error) {
sendUserNotification(@"I2P is done extracting", @"I2P is now installed and ready to run!");
- [self.swiftRuntime applicationDidFinishLaunching];
NSLog(@"Done extracting I2P");
- if (shouldAutoStartRouter) [self startupI2PRouter];
+
+ if (shouldAutoStartRouter) {
+ [sBridge startupI2PRouter:self.metaInfo.i2pBase javaBinPath:self.metaInfo.javaBinary];
+ [routerStatus setRouterRanByUs: true];
+ }
}];
} else {
- if (self.enableVerboseLogging) NSLog(@"I2P directory found!");
- if (shouldAutoStartRouter) [self startupI2PRouter];
- [self.swiftRuntime applicationDidFinishLaunching];
+ // I2P was already found extracted
+
+ if (shouldAutoStartRouter) {
+ [sBridge startupI2PRouter:self.metaInfo.i2pBase javaBinPath:self.metaInfo.javaBinary];
+ [routerStatus setRouterRanByUs: true];
+ }
}
#endif
@@ -411,15 +330,20 @@ void setGlobalRouterIsRunning(bool running)
int main(int argc, const char **argv)
{
NSApplication *app = [NSApplication sharedApplication];
- //NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
AppDelegate *appDelegate = [[AppDelegate alloc] initWithArgc:argc argv:argv];
app.delegate = appDelegate;
+ auto mainBundle = [NSBundle mainBundle];
+ NSString* stringNameBundle = [mainBundle objectForInfoDictionaryKey:(NSString *)kCFBundleNameKey];
+ if ([[NSRunningApplication runningApplicationsWithBundleIdentifier:[mainBundle bundleIdentifier]] count] > 1) {
+ [[NSAlert alertWithMessageText:[NSString stringWithFormat:@"Another copy of %@ is already running.",stringNameBundle]
+ defaultButton:nil alternateButton:nil otherButton:nil informativeTextWithFormat:@"This copy will now quit."] runModal];
+
+ [NSApp terminate:nil];
+ }
[NSBundle loadNibNamed:@"I2Launcher" owner:NSApp];
[NSApp run];
- // Handle any errors
- //[pool drain];
return 0;
}