Mac OSX Launcher: Common code for browser communication/control.

This commit is contained in:
meeh
2019-05-02 22:47:01 +00:00
parent d81f993f81
commit 84419bbf0b
3 changed files with 240 additions and 0 deletions

View File

@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" initialViewController="oLh-xo-y8T">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14460.31"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--Window Controller-->
<scene sceneID="g0w-9k-Acs">
<objects>
<windowController id="oLh-xo-y8T" sceneMemberID="viewController">
<window key="window" title="Window" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" frameAutosaveName="" animationBehavior="default" id="5Sr-7Y-gfA">
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
<rect key="contentRect" x="294" y="362" width="480" height="270"/>
<rect key="screenRect" x="0.0" y="0.0" width="1920" height="1177"/>
<connections>
<outlet property="delegate" destination="oLh-xo-y8T" id="Fxx-ke-F0n"/>
</connections>
</window>
<connections>
<segue destination="nXM-BR-Lxj" kind="relationship" relationship="window.shadowedContentViewController" id="3cB-Gf-aj2"/>
</connections>
</windowController>
<customObject id="K5y-Qa-lNJ" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="50" y="118"/>
</scene>
<!--Console View Controller-->
<scene sceneID="MSW-MZ-pqs">
<objects>
<viewController id="nXM-BR-Lxj" customClass="ConsoleViewController" customModule="I2PLauncher" customModuleProvider="target" sceneMemberID="viewController">
<view key="view" id="Omy-Aq-Pw7">
<rect key="frame" x="0.0" y="0.0" width="480" height="270"/>
<autoresizingMask key="autoresizingMask"/>
</view>
</viewController>
<customObject id="LZW-ak-seY" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="757" y="93"/>
</scene>
</scenes>
</document>

View File

@@ -0,0 +1,88 @@
//
// EmbeddedConsoleView.swift
// I2PLauncher
//
// Created by Mikal Villa on 08/12/2018.
// Copyright © 2018 The I2P Project. All rights reserved.
//
import AppKit
import WebKit
/*
protocol EConsoleViewWrapper {}
class WebViewSource {
class func webView() -> EConsoleViewWrapper {
if #available(OSX 10.12, *) {
//
return EmbeddedConsoleView(coder: NSCoder())!
} else {
// Sorry
return EmbeddedConsoleViewDummy()
}
}
}
extension EConsoleViewWrapper {
static func instantiate(frame frameRect: NSRect) -> EConsoleViewWrapper {
return WebViewSource.webView()
}
}
*/
class ConsoleWindowController: NSWindowController {
override func windowDidLoad() {
super.windowDidLoad()
/* let v: NSView = WebViewSource.webView() as! NSView
v.wantsLayer = true
self.window?.contentView?.addSubview(v)*/
}
}
class ConsoleViewController: NSViewController {
var webView: WKWebView!
let consoleWebUrl = URL(string: "http://127.0.0.1:7657")
override func loadView() {
let webConfiguration = WKWebViewConfiguration()
webView = WKWebView(frame: .zero, configuration: webConfiguration)
//webView.uiDelegate = self
view = webView
}
override func viewDidLoad() {
super.viewDidLoad()
webView.load(URLRequest(url: consoleWebUrl!))
}
}
/*
@available(OSX 10.12, *)
class EmbeddedConsoleView: WKWebView, EConsoleViewWrapper {
let consoleWebUrl = URL(string: "http://127.0.0.1:7657")
func setupWebViewForConsole(_ f: NSRect = NSRect(x: 0, y: 0, width: 800, height: 400)) {
self.allowsBackForwardNavigationGestures = true
self.configuration.preferences.javaScriptEnabled = true
self.configuration.preferences.plugInsEnabled = false
self.load(URLRequest(url: consoleWebUrl!))
}
override func viewWillDraw() {
super.viewWillDraw()
}
required init?(coder decoder: NSCoder) {
super.init(coder: decoder)
self.setupWebViewForConsole()
}
}
class EmbeddedConsoleViewDummy: NSView, EConsoleViewWrapper {}
*/

View File

@@ -0,0 +1,108 @@
//
// FirefoxManager.swift
// I2PLauncher
//
// Created by Mikal Villa on 08/12/2018.
// Copyright © 2018 The I2P Project. All rights reserved.
//
import Foundation
class FirefoxManager {
var firefoxAppPath = ""
private var isFirefoxFound = false
private var isFirefoxProfileExtracted = false
fileprivate func directoryExistsAtPath(_ path: String) -> Bool {
var isDirectory = ObjCBool(true)
let exists = FileManager.default.fileExists(atPath: path, isDirectory: &isDirectory)
return exists && isDirectory.boolValue
}
func IsFirefoxFound() -> Bool {
return self.isFirefoxFound
}
func IsProfileExtracted() -> Bool {
return self.isFirefoxProfileExtracted
}
// Since we execute in the "unix/POSIX way", we need the full path of the binary.
func bundleExecutableSuffixPath() -> String {
return "/Contents/MacOS/firefox"
}
func executeFirefox() -> Bool {
let fullExecPath = "\(self.firefoxAppPath)\(self.bundleExecutableSuffixPath())"
let firefoxProcess = Subprocess(executablePath: fullExecPath, arguments: [ "-profile", Preferences.shared()["I2Pref_firefoxProfilePath"] as! String, "http://127.0.0.1:7657/home" ])
DispatchQueue.global(qos: .background).async {
let _ = firefoxProcess.execute()
}
return true
}
/**
*
* First, try find I2P Browser, if it fails, then try Firefox or Firefox Developer.
*
* Instead of using hardcoded paths, or file search we use OS X's internal "registry" API
* and detects I2P Browser or Firefox by bundle name. (or id, but name is more readable)
*
*/
func tryAutoDetect() -> Bool {
var browserPath = NSWorkspace.shared.fullPath(forApplication: "I2P Browser")
if (browserPath == nil)
{
browserPath = NSWorkspace.shared.fullPath(forApplication: "Firefox")
if (browserPath == nil)
{
browserPath = NSWorkspace.shared.fullPath(forApplication: "Firefox Developer")
}
}
self.isFirefoxProfileExtracted = directoryExistsAtPath(Preferences.shared()["I2Pref_firefoxProfilePath"] as! String)
// If browserPath is still nil, then nothing above was found and we can return early.
if (browserPath == nil)
{
return false
}
let result = directoryExistsAtPath(browserPath!)
self.isFirefoxFound = result
if (result) {
self.firefoxAppPath = browserPath!
return true
}
return false
}
private static var sharedFirefoxManager: FirefoxManager = {
let firefoxMgr = FirefoxManager()
return firefoxMgr
}()
class func shared() -> FirefoxManager {
return sharedFirefoxManager
}
}
extension FirefoxManager {
func unzipProfile() -> Bool {
let resourceUrl = Bundle.main.url(forResource: "profile", withExtension: "tgz")
let profileTgz = resourceUrl!.path
let unzipProc = Subprocess(executablePath: "/usr/bin/tar", arguments: ["-xf",profileTgz,"-C",NSString(format: "%@/Library/Application Support/i2p", NSHomeDirectory()) as String])
DispatchQueue.global(qos: .background).async {
let proc = unzipProc.execute(captureOutput: true)
print("Firefox Profile Extraction Errors: \(proc?.errors ?? "false")")
print("Firefox Profile Extraction Output: \(proc?.output ?? "false")")
}
return false
}
}