Mac OS X Launcher: more cleanup and some bugfixes.

This commit is contained in:
meeh
2018-09-20 03:20:39 +00:00
parent 3c0a8cf4ab
commit e8decff5cd
8 changed files with 83 additions and 394 deletions

View File

@@ -13,10 +13,10 @@
#endif #endif
#include <Cocoa/Cocoa.h> #include <Cocoa/Cocoa.h>
#include "SBridge.h"
#include "RouterTask.h" #include "RouterTask.h"
#include "JavaHelper.h"
#define DEF_I2P_VERSION "0.9.36" #define DEF_I2P_VERSION "0.9.36"
@@ -34,8 +34,6 @@
@class ExtractMetaInfo; @class ExtractMetaInfo;
@interface ExtractMetaInfo : NSObject @interface ExtractMetaInfo : NSObject
@property (copy) NSString* i2pBase; @property (copy) NSString* i2pBase;
@property (copy) NSString* javaBinary; @property (copy) NSString* javaBinary;
@@ -63,7 +61,7 @@ inline std::string getDefaultBaseDir()
return i2pBaseDir; return i2pBaseDir;
} }
inline void sendUserNotification(NSString* title, NSString* informativeText, NSImage* contentImage = NULL, bool makeSound = false) { inline void sendUserNotification(NSString* title, NSString* informativeText, bool makeSound = false) {
NSUserNotification *userNotification = [[NSUserNotification alloc] init]; NSUserNotification *userNotification = [[NSUserNotification alloc] init];
userNotification.title = title; userNotification.title = title;
@@ -80,32 +78,9 @@ inline void sendUserNotification(NSString* title, NSString* informativeText, NSI
[[NSUserNotificationCenter defaultUserNotificationCenter] scheduleNotification:userNotification]; [[NSUserNotificationCenter defaultUserNotificationCenter] scheduleNotification:userNotification];
}; };
using maybeAnRouterRunner = I2PRouterTask*;
std::vector<std::string> buildClassPath(std::string basePath);
extern JvmListSharedPtr gRawJvmList;
// DO NOT ACCESS THIS GLOBAL VARIABLE DIRECTLY.
static std::mutex globalRouterStatusMutex;
static maybeAnRouterRunner globalRouterStatus = maybeAnRouterRunner{};
static bool isRuterRunning = false;
maybeAnRouterRunner getGlobalRouterObject();
void setGlobalRouterObject(I2PRouterTask* newRouter);
bool getGlobalRouterIsRunning();
void setGlobalRouterIsRunning(bool running);
#include "SBridge.h"
#endif #endif
@class MenuBarCtrl; @interface AppDelegate : NSObject <NSUserNotificationCenterDelegate, NSApplicationDelegate>
@interface AppDelegate : NSObject <NSUserNotificationCenterDelegate, NSApplicationDelegate> {
@public
//NSImageView *imageCell;
}
@property BOOL enableLogging; @property BOOL enableLogging;
@property BOOL enableVerboseLogging; @property BOOL enableVerboseLogging;
@property (assign) SwiftMainDelegate *swiftRuntime; @property (assign) SwiftMainDelegate *swiftRuntime;
@@ -118,12 +93,7 @@ void setGlobalRouterIsRunning(bool running);
- (void) applicationDidFinishLaunching:(NSNotification *)aNotification; - (void) applicationDidFinishLaunching:(NSNotification *)aNotification;
- (void) applicationWillTerminate:(NSNotification *)aNotification; - (void) applicationWillTerminate:(NSNotification *)aNotification;
- (void) setApplicationDefaultPreferences; - (void) setApplicationDefaultPreferences;
- (void) userChooseJavaHome;
- (AppDelegate *) initWithArgc:(int)argc argv:(const char **)argv; - (AppDelegate *) initWithArgc:(int)argc argv:(const char **)argv;
#ifdef __cplusplus
- (void) startupI2PRouter;
- (NSString *) userSelectJavaHome:(JvmListPtr)rawJvmList;
#endif
- (BOOL) userNotificationCenter:(NSUserNotificationCenter *)center - (BOOL) userNotificationCenter:(NSUserNotificationCenter *)center
shouldPresentNotification:(NSUserNotification *)notification; shouldPresentNotification:(NSUserNotification *)notification;
@end @end

View File

@@ -26,29 +26,29 @@ import AppKit
} }
@objc func getRouterIsRunning() -> Bool { @objc func getRouterIsRunning() -> Bool {
if (RouterProcessStatus.isRouterRunning) { return RouterProcessStatus.isRouterRunning
return false;
} else {
let running: Bool = RouterProcessStatus.isRouterRunning
return running
}
} }
@objc func getJavaHome() -> String { @objc func getJavaHome() -> String {
return RouterProcessStatus.knownJavaBinPath! return RouterProcessStatus.knownJavaBinPath!
} }
@objc func setJavaHome(_ home: String) {
NSLog("Setting known java to %s", home)
RouterProcessStatus.knownJavaBinPath = home
}
} }
extension RouterProcessStatus { extension RouterProcessStatus {
static var isRouterRunning : Bool = false static var isRouterRunning : Bool = false
static var isRouterChildProcess : Bool = false static var isRouterChildProcess : Bool = false
static var routerVersion : String? = Optional.none static var routerVersion : String? = Optional.none
static var routerUptime : String? = Optional.none static var routerUptime : String? = Optional.none{
//Called before the change
willSet(newValue){
print("RouterProcessStatus.routerUptime will change from ", (self.routerUptime ?? "nil"), " to "+(newValue ?? "nil"))
}
//Called after the change
didSet{
print("RouterProcessStatus.routerUptime did change to "+self.routerUptime!)
}
}
static var routerStartedAt : Date? = Optional.none static var routerStartedAt : Date? = Optional.none
static var knownJavaBinPath : String? = Optional.none static var knownJavaBinPath : String? = Optional.none
static var i2pDirectoryPath : String = NSHomeDirectory() + "/Library/I2P" static var i2pDirectoryPath : String = NSHomeDirectory() + "/Library/I2P"

View File

@@ -1,167 +0,0 @@
#pragma once
#ifdef __cplusplus
#include <memory.h>
#include <string.h>
#include <stdlib.h>
#include <Foundation/Foundation.h>
#include <CoreFoundation/CoreFoundation.h>
#include <CoreFoundation/CFStream.h>
#include <CoreFoundation/CFPropertyList.h>
#include <CoreFoundation/CFDictionary.h>
#include <CoreFoundation/CFArray.h>
#include <CoreFoundation/CFString.h>
#include "RouterTask.h"
#define DEF_MIN_JVM_VER "1.7+"
#include "include/strutil.hpp"
#include <functional>
#include <memory>
#include <list>
class JvmVersion
{
public:
std::string JVMName;
std::string JVMHomePath;
std::string JVMPlatformVersion;
inline const char * ToCString()
{
std::stringstream ss;
ss << "JvmVersion(name=" << JVMName.c_str() << ",version=";
ss << JVMPlatformVersion.c_str() << ",home=" << JVMHomePath.c_str() << ")";
std::string s = ss.str();
return s.c_str();
}
inline bool HasContent()
{
return (
std::strlen(JVMName.c_str()) > 0 &&
std::strlen(JVMHomePath.c_str()) > 0 &&
std::strlen(JVMPlatformVersion.c_str()) > 0
);
}
};
typedef std::shared_ptr<JvmVersion> JvmVersionPtr;
typedef std::shared_ptr<std::list<JvmVersionPtr> > JvmListPtr;
typedef std::shared_ptr<std::list<std::shared_ptr<JvmVersion> > > JvmListSharedPtr;
typedef void(^MenuBarControllerActionBlock)(BOOL active);
extern JvmListSharedPtr gRawJvmList;
class JvmHomeContext : public std::enable_shared_from_this<JvmHomeContext>
{
public:
inline void setJvm(JvmVersionPtr* current)
{
mCurrent = *current;
}
inline JvmListPtr getJvmList()
{
return gRawJvmList;
}
inline std::shared_ptr<JvmHomeContext> getContext()
{
return shared_from_this();
}
inline std::string getJavaHome()
{
if (mCurrent)
{
return mCurrent->JVMHomePath;
}
return gRawJvmList->back()->JVMHomePath;
}
private:
JvmVersionPtr mCurrent;
};
static void processJvmEntry (const void* key, const void* value, void* context) {
//CFShow(key);
//CFShow(value);
// The reason for using strprintf is to "force" a copy of the values,
// since local variables gets deleted once this function returns.
auto currentJvm = reinterpret_cast<JvmVersion*>(context);
if (CFEqual((CFStringRef)key,CFSTR("JVMName"))) {
auto strVal = extractString((CFStringRef)value);
currentJvm->JVMName = strprintf("%s",strVal.c_str());
}
if (CFEqual((CFStringRef)key,CFSTR("JVMHomePath"))) {
auto strVal = extractString((CFStringRef)value);
currentJvm->JVMHomePath = strprintf("%s",strVal.c_str());
}
if (CFEqual((CFStringRef)key,CFSTR("JVMPlatformVersion"))) {
auto strVal = extractString((CFStringRef)value);
currentJvm->JVMPlatformVersion = strprintf("%s",strVal.c_str());
}
}
static void processJvmPlistEntries (const void* item, void* context) {
CFDictionaryRef dict = CFDictionaryCreateCopy(kCFAllocatorDefault, (CFDictionaryRef)item);
JvmVersionPtr currentJvmPtr = std::shared_ptr<JvmVersion>(new JvmVersion());
struct CFunctional
{
static void applier(const void* key, const void* value, void* context){
// The reason for using strprintf is to "force" a copy of the values,
// since local variables gets deleted once this function returns.
auto currentJvm = static_cast<JvmVersion*>(context);
if (CFEqual((CFStringRef)key,CFSTR("JVMName"))) {
auto d = extractString((CFStringRef)value);
currentJvm->JVMName = trim_copy(d);
}
if (CFEqual((CFStringRef)key,CFSTR("JVMHomePath"))) {
auto d = extractString((CFStringRef)value);
currentJvm->JVMHomePath = trim_copy(d);
}
if (CFEqual((CFStringRef)key,CFSTR("JVMPlatformVersion"))) {
auto d = extractString((CFStringRef)value);
currentJvm->JVMPlatformVersion = trim_copy(d);
}
}
};
CFDictionaryApplyFunction(dict, CFunctional::applier, (void*)currentJvmPtr.get());
if (currentJvmPtr->HasContent())
{
printf("Found JVM: %s\n\n", currentJvmPtr->ToCString());
gRawJvmList->push_back(currentJvmPtr);
}
}
static void listAllJavaInstallsAvailable()
{
auto javaHomeRes = check_output({"/usr/libexec/java_home","-v",DEF_MIN_JVM_VER,"-X"});
CFDataRef javaHomes = CFDataCreate(NULL, (const UInt8 *)javaHomeRes.buf.data(), strlen(javaHomeRes.buf.data()));
CFPropertyListRef propertyList = CFPropertyListCreateWithData(kCFAllocatorDefault, javaHomes, kCFPropertyListImmutable, NULL, NULL);
auto jCount = CFArrayGetCount((CFArrayRef)propertyList);
CFArrayApplyFunction((CFArrayRef)propertyList, CFRangeMake(0, jCount), processJvmPlistEntries, NULL);
//CFShow(propertyList);
}
#endif

View File

@@ -2,19 +2,13 @@
#include <dispatch/dispatch.h> #include <dispatch/dispatch.h>
#include <memory.h> #include <memory.h>
#include <string.h>
#include <Cocoa/Cocoa.h> #include <Cocoa/Cocoa.h>
#import <AppKit/AppKit.h> #import <AppKit/AppKit.h>
#ifdef __cplusplus #ifdef __cplusplus
#include "include/subprocess.hpp" #include <vector>
#include <string>
using namespace subprocess;
class JavaRunner;
typedef std::function<void(void)> fp_t;
typedef std::function<void(JavaRunner *ptr)> fp_proc_t;
const std::vector<NSString*> defaultStartupFlags { const std::vector<NSString*> defaultStartupFlags {
@"-Xmx512M", @"-Xmx512M",
@@ -32,31 +26,6 @@ const std::vector<std::string> defaultFlagsForExtractorJob {
"-Djava.awt.headless=true" "-Djava.awt.headless=true"
}; };
/**
*
* class JavaRunner
*
**/
class JavaRunner
{
public:
// copy fn
JavaRunner(std::string& javaBin, std::string& arguments, std::string& i2pBaseDir, const fp_proc_t& executingFn, const fp_t& cb);
~JavaRunner() = default;
void requestRouterShutdown();
std::future<int> execute();
std::shared_ptr<subprocess::Popen> javaProcess;
std::string javaBinaryPath;
std::string javaRouterArgs;
std::string execLine;
std::string _i2pBaseDir;
private:
const fp_proc_t& executingFn;
const fp_t& exitCallbackFn;
};
#endif #endif

View File

@@ -9,6 +9,7 @@
#import "I2PLauncher-Swift.h" #import "I2PLauncher-Swift.h"
#include "AppDelegate.h" #include "AppDelegate.h"
#endif #endif
#include "include/PidWatcher.h" #include "include/PidWatcher.h"
#import <AppKit/AppKit.h> #import <AppKit/AppKit.h>
@@ -52,23 +53,13 @@
[stdoutFileHandle waitForDataInBackgroundAndNotify]; [stdoutFileHandle waitForDataInBackgroundAndNotify];
[self.routerTask setTerminationHandler:^(NSTask* task) { [self.routerTask setTerminationHandler:^(NSTask* task) {
// Cleanup
NSLog(@"termHandler triggered!"); NSLog(@"termHandler triggered!");
auto swiftRouterStatus = [[RouterProcessStatus alloc] init]; auto swiftRouterStatus = [[RouterProcessStatus alloc] init];
[swiftRouterStatus setRouterStatus: true]; [swiftRouterStatus setRouterStatus: false];
[swiftRouterStatus setRouterRanByUs: false];
sendUserNotification(APP_IDSTR, @"I2P Router has stopped"); sendUserNotification(APP_IDSTR, @"I2P Router has stopped");
// Cleanup
//self.isRouterRunning = NO;
}]; }];
/*
self.readLogHandle = [self.processPipe fileHandleForReading];
NSData *inData = nil;
self.totalLogData = [[[NSMutableData alloc] init] autorelease];
while ((inData = [self.readLogHandle availableData]) &&
[inData length]) {
[self.totalLogData appendData:inData];
}
*/
return self; return self;
} }
@@ -91,63 +82,25 @@
- (int) execute - (int) execute
{ {
@try { @try {
[self.routerTask launch]; [self.routerTask launch];
watchPid([self.routerTask processIdentifier]); watchPid([self.routerTask processIdentifier]);
self.isRouterRunning = YES; self.isRouterRunning = YES;
return 1; return 1;
} }
@catch (NSException *e) @catch (NSException *e)
{ {
NSLog(@"Expection occurred %@", [e reason]); NSLog(@"Expection occurred %@", [e reason]);
return 0; auto swiftRouterStatus = [[RouterProcessStatus alloc] init];
[swiftRouterStatus setRouterStatus: false];
[swiftRouterStatus setRouterRanByUs: false];
sendUserNotification(@"An error occured, can't start the I2P Router", [e reason]);
return 0;
} }
} }
- (int) getPID - (int) getPID
{ {
return [self.routerTask processIdentifier]; return [self.routerTask processIdentifier];
} }
@end @end
#ifdef __cplusplus
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)
{
execLine = javaBinaryPath;
execLine += " " + std::string(javaRouterArgs.c_str());
printf("CLI: %s\n",execLine.c_str());
javaProcess = std::shared_ptr<Popen>(new Popen(execLine, environment{{
{"I2PBASE", _i2pBaseDir},
{"JAVA_OPTS", getenv("JAVA_OPTS")}
}}, defer_spawn{true}));
}
void JavaRunner::requestRouterShutdown()
{
// SIGHUP
javaProcess->kill(1);
}
std::future<int> JavaRunner::execute()
{
try {
auto executingFn = dispatch_block_create(DISPATCH_BLOCK_INHERIT_QOS_CLASS, ^{
this->executingFn(this);
});
dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), executingFn);
dispatch_block_wait(executingFn, DISPATCH_TIME_FOREVER);
// Here, the process is done executing.
printf("Finished executingFn - Runs callbackFn\n");
this->exitCallbackFn();
return std::async(std::launch::async, []{ return 0; });
} catch (std::exception* ex) {
printf("ERROR: %s\n", ex->what());
return std::async(std::launch::async, []{ return 1; });
}
}
#endif

View File

@@ -7,6 +7,51 @@
// //
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
#import <Cocoa/Cocoa.h>
#ifdef __cplusplus
#include <memory>
#include <future>
#include <glob.h>
#include <string>
#include <vector>
#include "include/fn.h"
std::future<int> startupRouter(NSString* javaBin, NSArray<NSString*>* arguments, NSString* i2pBaseDir);
namespace osx {
inline void openUrl(NSString* url)
{
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString: url]];
}
}
inline std::vector<std::string> globVector(const std::string& pattern){
glob_t glob_result;
glob(pattern.c_str(),GLOB_TILDE,NULL,&glob_result);
std::vector<std::string> files;
for(unsigned int i=0;i<glob_result.gl_pathc;++i){
files.push_back(std::string(glob_result.gl_pathv[i]));
}
globfree(&glob_result);
return files;
}
inline std::string buildClassPathForObjC(std::string basePath)
{
NSBundle *launcherBundle = [NSBundle mainBundle];
auto jarList = globVector(basePath+std::string("/lib/*.jar"));
std::string classpathStrHead = "-classpath";
std::string classpathStr = "";
classpathStr += [[launcherBundle pathForResource:@"launcher" ofType:@"jar"] UTF8String];
std::string prefix(basePath);
prefix += "/lib/";
for_each(jarList, [&classpathStr](std::string str){ classpathStr += std::string(":") + str; });
return classpathStr;
}
#endif
@interface SBridge : NSObject @interface SBridge : NSObject
- (NSString*) buildClassPath:(NSString*)i2pPath; - (NSString*) buildClassPath:(NSString*)i2pPath;

View File

@@ -33,8 +33,6 @@ std::future<int> startupRouter(NSString* javaBin, NSArray<NSString*>* arguments,
options.arguments = arguments; options.arguments = arguments;
options.i2pBaseDir = i2pBaseDir; options.i2pBaseDir = i2pBaseDir;
auto instance = [[I2PRouterTask alloc] initWithOptions: options]; auto instance = [[I2PRouterTask alloc] initWithOptions: options];
//setGlobalRouterObject(instance);
//NSThread *thr = [[NSThread alloc] initWithTarget:instance selector:@selector(execute) object:nil];
[instance execute]; [instance execute];
sendUserNotification(APP_IDSTR, @"The I2P router is starting up."); sendUserNotification(APP_IDSTR, @"The I2P router is starting up.");
auto pid = [instance getPID]; auto pid = [instance getPID];
@@ -53,37 +51,6 @@ std::future<int> startupRouter(NSString* javaBin, NSArray<NSString*>* arguments,
} }
} }
namespace osx {
inline void openUrl(NSString* url)
{
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString: url]];
}
}
inline std::vector<std::string> globVector(const std::string& pattern){
glob_t glob_result;
glob(pattern.c_str(),GLOB_TILDE,NULL,&glob_result);
std::vector<std::string> files;
for(unsigned int i=0;i<glob_result.gl_pathc;++i){
files.push_back(std::string(glob_result.gl_pathv[i]));
}
globfree(&glob_result);
return files;
}
inline std::string buildClassPathForObjC(std::string basePath)
{
NSBundle *launcherBundle = [NSBundle mainBundle];
auto jarList = globVector(basePath+std::string("/lib/*.jar"));
std::string classpathStrHead = "-classpath";
std::string classpathStr = "";
classpathStr += [[launcherBundle pathForResource:@"launcher" ofType:@"jar"] UTF8String];
std::string prefix(basePath);
prefix += "/lib/";
for_each(jarList, [&classpathStr](std::string str){ classpathStr += std::string(":") + str; });
return classpathStr;
}
@implementation SBridge @implementation SBridge

View File

@@ -11,14 +11,6 @@
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
#import <Foundation/NSFileManager.h> #import <Foundation/NSFileManager.h>
#include <CoreFoundation/CoreFoundation.h>
#include <CoreFoundation/CFStream.h>
#include <CoreFoundation/CFPropertyList.h>
#include <CoreFoundation/CFDictionary.h>
#include <CoreFoundation/CFArray.h>
#include <CoreFoundation/CFString.h>
#include <CoreFoundation/CFPreferences.h> #include <CoreFoundation/CFPreferences.h>
#import <objc/Object.h> #import <objc/Object.h>
@@ -30,7 +22,6 @@
#include "AppDelegate.h" #include "AppDelegate.h"
#include "RouterTask.h" #include "RouterTask.h"
#include "JavaHelper.h"
#include "include/fn.h" #include "include/fn.h"
#include "include/portcheck.h" #include "include/portcheck.h"
#import "SBridge.h" #import "SBridge.h"
@@ -111,13 +102,6 @@ using namespace subprocess;
cli.push_back(jarfile); cli.push_back(jarfile);
cli.push_back("net.i2p.launchers.BaseExtractor"); cli.push_back("net.i2p.launchers.BaseExtractor");
auto rs = [[RouterProcessStatus alloc] init]; auto rs = [[RouterProcessStatus alloc] init];
NSString* jh = [rs getJavaHome];
if (jh != nil) {
NSLog(@"jh er %@", jh);
}
NSString* newString = [NSString stringWithFormat:@"file://%@", rs.getJavaHome];
NSURL *baseURL = [NSURL fileURLWithPath:newString];
std::string execStr = std::string([rs.getJavaHome UTF8String]); std::string execStr = std::string([rs.getJavaHome UTF8String]);
for_each(cli, [&execStr](std::string str){ execStr += std::string(" ") + str; }); for_each(cli, [&execStr](std::string str){ execStr += std::string(" ") + str; });
@@ -132,9 +116,7 @@ using namespace subprocess;
NSLog(@"Extraction exit code %@",[NSString stringWithUTF8String:(std::to_string(extractStatus)).c_str()]); NSLog(@"Extraction exit code %@",[NSString stringWithUTF8String:(std::to_string(extractStatus)).c_str()]);
if (extractStatus == 0) if (extractStatus == 0)
{ {
//success = YES; NSLog(@"Extraction complete!");
NSLog(@"Time to detect I2P version in install directory");
[self.swiftRuntime findInstalledI2PVersion];
} }
} catch (subprocess::OSError &err) { } catch (subprocess::OSError &err) {
@@ -146,7 +128,6 @@ using namespace subprocess;
// All done. Assume success and error are already set. // All done. Assume success and error are already set.
dispatch_async(dispatch_get_main_queue(), ^{ dispatch_async(dispatch_get_main_queue(), ^{
//sendUserNotification(APP_IDSTR, @"Extraction complete!", self.contentImage);
if (completion) { if (completion) {
completion(success, error); completion(success, error);
} }
@@ -158,45 +139,15 @@ using namespace subprocess;
NSLog(@"Exception: %@", errMsg); NSLog(@"Exception: %@", errMsg);
} }
}); });
}
- (NSString *)userSelectJavaHome:(JvmListPtr)rawJvmList
{
NSString *appleScriptString = @"set jvmlist to {\"Newest\"";
for (auto item : *rawJvmList) {
auto str = strprintf(",\"%s\"", item->JVMName.c_str()).c_str();
NSString* tmp = [NSString stringWithUTF8String:str];
appleScriptString = [appleScriptString stringByAppendingString:tmp];
}
appleScriptString = [appleScriptString stringByAppendingString:@"}\nchoose from list jvmlist\n"];
NSAppleScript *theScript = [[NSAppleScript alloc] initWithSource:appleScriptString];
NSDictionary *theError = nil;
NSString* userResult = [[theScript executeAndReturnError: &theError] stringValue];
NSLog(@"User choosed %@.\n", userResult);
if (theError != nil)
{
NSLog(@"Error: %@.\n", theError);
}
return userResult;
} }
- (void)setApplicationDefaultPreferences { - (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<const char *>(tmpStdStr.c_str()), kCFStringEncodingUTF8);
[self.userPreferences registerDefaults:@{ [self.userPreferences registerDefaults:@{
@"javaHome" : (NSString *)cfDefaultHome,
@"lastI2PVersion" : (NSString *)CFSTR(DEF_I2P_VERSION),
@"enableLogging": @YES, @"enableLogging": @YES,
@"enableVerboseLogging": @YES, @"enableVerboseLogging": @YES,
@"autoStartRouter": @YES, @"autoStartRouter": @YES,
@"i2pBaseDirectory": (NSString *)CFStringCreateWithCString(NULL, const_cast<const char *>(getDefaultBaseDir().c_str()), kCFStringEncodingUTF8) @"i2pBaseDirectory": (NSString *)CFStringCreateWithCString(NULL, const_cast<const char *>(getDefaultBaseDir().c_str()), kCFStringEncodingUTF8)
}]; }];
if (self.enableVerboseLogging) NSLog(@"Default JVM home preference set to: %@", cfDefaultHome);
auto dict = [self.userPreferences dictionaryRepresentation]; auto dict = [self.userPreferences dictionaryRepresentation];
[self.userPreferences setPersistentDomain:dict forName:NSAPPDOMAIN]; [self.userPreferences setPersistentDomain:dict forName:NSAPPDOMAIN];
@@ -205,10 +156,9 @@ using namespace subprocess;
CFPreferencesAppSynchronize(kCFPreferencesCurrentApplication); CFPreferencesAppSynchronize(kCFPreferencesCurrentApplication);
if (self.enableVerboseLogging) NSLog(@"Default preferences stored!"); if (self.enableVerboseLogging) NSLog(@"Default preferences stored!");
#endif
} }
#endif
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification { - (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
@@ -231,7 +181,6 @@ using namespace subprocess;
#ifdef __cplusplus #ifdef __cplusplus
//gRawJvmList = std::make_shared<std::list<JvmVersionPtr> >(std::list<JvmVersionPtr>());
RouterProcessStatus* routerStatus = [[RouterProcessStatus alloc] init]; RouterProcessStatus* routerStatus = [[RouterProcessStatus alloc] init];
std::string i2pBaseDir(getDefaultBaseDir()); std::string i2pBaseDir(getDefaultBaseDir());
@@ -255,6 +204,7 @@ using namespace subprocess;
NSBundle *launcherBundle = [NSBundle mainBundle]; NSBundle *launcherBundle = [NSBundle mainBundle];
auto sBridge = [[SBridge alloc] init];
// Helper object to hold statefull path information // Helper object to hold statefull path information
self.metaInfo = [[ExtractMetaInfo alloc] init]; self.metaInfo = [[ExtractMetaInfo alloc] init];
@@ -269,8 +219,6 @@ using namespace subprocess;
std::string jarfile("-cp "); std::string jarfile("-cp ");
jarfile += [self.metaInfo.zipFile UTF8String]; jarfile += [self.metaInfo.zipFile UTF8String];
auto sBridge = [[SBridge alloc] init];
// Initialize the Swift environment (the UI components) // Initialize the Swift environment (the UI components)
[self.swiftRuntime applicationDidFinishLaunching]; [self.swiftRuntime applicationDidFinishLaunching];
@@ -286,6 +234,8 @@ using namespace subprocess;
sendUserNotification(@"I2P is done extracting", @"I2P is now installed and ready to run!"); sendUserNotification(@"I2P is done extracting", @"I2P is now installed and ready to run!");
NSLog(@"Done extracting I2P"); NSLog(@"Done extracting I2P");
NSLog(@"Time to detect I2P version in install directory");
[self.swiftRuntime findInstalledI2PVersion];
if (shouldAutoStartRouter) { if (shouldAutoStartRouter) {
[sBridge startupI2PRouter:self.metaInfo.i2pBase javaBinPath:self.metaInfo.javaBinary]; [sBridge startupI2PRouter:self.metaInfo.i2pBase javaBinPath:self.metaInfo.javaBinary];
[routerStatus setRouterRanByUs: true]; [routerStatus setRouterRanByUs: true];
@@ -294,6 +244,8 @@ using namespace subprocess;
} else { } else {
// I2P was already found extracted // I2P was already found extracted
NSLog(@"Time to detect I2P version in install directory");
[self.swiftRuntime findInstalledI2PVersion];
if (shouldAutoStartRouter) { if (shouldAutoStartRouter) {
[sBridge startupI2PRouter:self.metaInfo.i2pBase javaBinPath:self.metaInfo.javaBinary]; [sBridge startupI2PRouter:self.metaInfo.i2pBase javaBinPath:self.metaInfo.javaBinary];