diff --git a/extension/background.js b/extension/background.js index 5e487cf..e6fba2b 100644 --- a/extension/background.js +++ b/extension/background.js @@ -673,6 +673,10 @@ function findRoute(path) { let port; async function onMessage(req) { + // Safari / Safari extension app API forces you to adopt their + // {name, userInfo} structure for the request. + if (req.name === 'ToSafari') req = req.userInfo; + if (req.buf) req.buf = atob(req.buf); console.log('req', req); @@ -712,6 +716,16 @@ function tryConnect() { port = chrome.runtime.connectNative('com.rsnous.tabfs'); port.onMessage.addListener(onMessage); port.onDisconnect.addListener(p => {console.log('disconnect', p)}); + + // Safari is very weird -- it has this native app that we have to talk to, + // so we poke that app to wake it up, get it to start the TabFS process, + // and get it to start calling us whenever TabFS wants to do an FS call. + // Is there a better way to do this? + if (chrome.runtime.getURL('/').startsWith('safari-web-extension://')) { // Safari-only + chrome.runtime.sendNativeMessage('com.rsnous.tabfs', {op: 'safari_did_connect'}, function(resp) { + console.log(resp); + }); + } } if (!TESTING) { diff --git a/extension/safari/TabFS/TabFS Extension/FSProcessManager.swift b/extension/safari/TabFS/TabFS Extension/FSProcessManager.swift new file mode 100644 index 0000000..d17d934 --- /dev/null +++ b/extension/safari/TabFS/TabFS Extension/FSProcessManager.swift @@ -0,0 +1,72 @@ +// +// FSProcessManager.swift +// TabFS +// +// Created by Omar Rizwan on 1/31/21. +// + +import Foundation + +import SafariServices.SFSafariApplication + +let extensionBundleIdentifier = "com.rsnous.TabFS-Extension" + +class FSProcessManager { + static let shared = FSProcessManager() + + // FIXME: should accept XPC connection to extension + // so it can get replies (??) + + var fs: Process! + var fsInput: FileHandle! + var fsOutput: FileHandle! + + func start() { + fs = Process() + fs.executableURL = URL(fileURLWithPath: "/Users/osnr/Code/tabfs/fs/tabfs") + fs.arguments = [] + + let inputPipe = Pipe(), outputPipe = Pipe() + fs.standardInput = inputPipe + fs.standardOutput = outputPipe + + try! fs.run() + + fsInput = inputPipe.fileHandleForWriting + fsOutput = outputPipe.fileHandleForReading +// +// SFSafariApplication.dispatchMessage( +// withName: "ToSafari", +// toExtensionWithIdentifier: extensionBundleIdentifier, +// userInfo: [:] +// ) { error in +// debugPrint("Message attempted. Error info: \(String.init(describing: error))") +// } + + DispatchQueue.global(qos: .background).async { + while true { + let req = self.awaitRequest() + + SFSafariApplication.dispatchMessage( + withName: "ToSafari", + toExtensionWithIdentifier: extensionBundleIdentifier, + userInfo: req + ) { error in + debugPrint("Message attempted. Error info: \(String.init(describing: error))") + } + } + } + } + + func awaitRequest() -> [String: Any] { + let length = fsOutput.readData(ofLength: 4).withUnsafeBytes { + $0.load(as: UInt32.self) + } + let data = fsOutput.readData(ofLength: Int(length)) + return try! JSONSerialization.jsonObject(with: data, options: []) as! [String: Any] + } + + func respond(_ resp: [AnyHashable: Any]) { + try! fsInput.write(JSONSerialization.data(withJSONObject: resp, options: [])) + } +} diff --git a/extension/safari/TabFS/TabFS Extension/SafariWebExtensionHandler.swift b/extension/safari/TabFS/TabFS Extension/SafariWebExtensionHandler.swift index f026b0b..6ae1aae 100644 --- a/extension/safari/TabFS/TabFS Extension/SafariWebExtensionHandler.swift +++ b/extension/safari/TabFS/TabFS Extension/SafariWebExtensionHandler.swift @@ -6,21 +6,38 @@ // import SafariServices +import SafariServices.SFSafariApplication import os.log -let SFExtensionMessageKey = "message" - class SafariWebExtensionHandler: NSObject, NSExtensionRequestHandling { - + func beginRequest(with context: NSExtensionContext) { + + os_log(.default, "Received message from browser.runtime.sendNativefffMessage: %@", context as! CVarArg) + let item = context.inputItems[0] as! NSExtensionItem - let message = item.userInfo?[SFExtensionMessageKey] - os_log(.default, "Received message from browser.runtime.sendNativeMessage: %@", message as! CVarArg) - - let response = NSExtensionItem() - response.userInfo = [ SFExtensionMessageKey: [ "Response to": message ] ] - - context.completeRequest(returningItems: [response], completionHandler: nil) + guard let message = item.userInfo?["message"] as? [AnyHashable: Any] else { return } + + if message["op"] as! String == "safari_did_connect" { + FSProcessManager.shared.start() + + let response = NSExtensionItem() + response.userInfo = [ "message": [ "aResponse to": "moop" ] ] + context.completeRequest(returningItems: [response], completionHandler: nil) + + return + } +// +// os_log(.default, "Received message from browser.runtime.sendNativeMessage: %@", op as! CVarArg) + + FSProcessManager.shared.respond(message) +// +// let response = NSExtensionItem() +// response.userInfo = [ "message": [ "Response to": op ] ] +// +// // How do I get too the app???? +// +// context.completeRequest(returningItems: [response], completionHandler: nil) } } diff --git a/extension/safari/TabFS/TabFS.xcodeproj/project.pbxproj b/extension/safari/TabFS/TabFS.xcodeproj/project.pbxproj index 5885330..4b063e1 100644 --- a/extension/safari/TabFS/TabFS.xcodeproj/project.pbxproj +++ b/extension/safari/TabFS/TabFS.xcodeproj/project.pbxproj @@ -18,6 +18,7 @@ F0442A1E25C7507500D998A5 /* safari in Resources */ = {isa = PBXBuildFile; fileRef = F0442A1A25C7507500D998A5 /* safari */; }; F0442A1F25C7507500D998A5 /* manifest.json in Resources */ = {isa = PBXBuildFile; fileRef = F0442A1B25C7507500D998A5 /* manifest.json */; }; F0442A2025C7507500D998A5 /* vendor in Resources */ = {isa = PBXBuildFile; fileRef = F0442A1C25C7507500D998A5 /* vendor */; }; + F068D65625C7C66700DB3AB5 /* FSProcessManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = F068D65225C77F7600DB3AB5 /* FSProcessManager.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -61,6 +62,7 @@ F0442A1A25C7507500D998A5 /* safari */ = {isa = PBXFileReference; lastKnownFileType = folder; name = safari; path = ../..; sourceTree = ""; }; F0442A1B25C7507500D998A5 /* manifest.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; name = manifest.json; path = ../../../manifest.json; sourceTree = ""; }; F0442A1C25C7507500D998A5 /* vendor */ = {isa = PBXFileReference; lastKnownFileType = folder; name = vendor; path = ../../../vendor; sourceTree = ""; }; + F068D65225C77F7600DB3AB5 /* FSProcessManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FSProcessManager.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -125,6 +127,7 @@ F0442A0A25C7507400D998A5 /* TabFS Extension */ = { isa = PBXGroup; children = ( + F068D65225C77F7600DB3AB5 /* FSProcessManager.swift */, F0442A1825C7507500D998A5 /* Resources */, F0442A0B25C7507400D998A5 /* SafariWebExtensionHandler.swift */, F0442A0D25C7507400D998A5 /* Info.plist */, @@ -257,6 +260,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + F068D65625C7C66700DB3AB5 /* FSProcessManager.swift in Sources */, F0442A0C25C7507400D998A5 /* SafariWebExtensionHandler.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/extension/safari/TabFS/TabFS.xcodeproj/project.xcworkspace/xcuserdata/osnr.xcuserdatad/UserInterfaceState.xcuserstate b/extension/safari/TabFS/TabFS.xcodeproj/project.xcworkspace/xcuserdata/osnr.xcuserdatad/UserInterfaceState.xcuserstate index 4a4220c..231f2f7 100644 Binary files a/extension/safari/TabFS/TabFS.xcodeproj/project.xcworkspace/xcuserdata/osnr.xcuserdatad/UserInterfaceState.xcuserstate and b/extension/safari/TabFS/TabFS.xcodeproj/project.xcworkspace/xcuserdata/osnr.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/extension/safari/TabFS/TabFS.xcodeproj/xcuserdata/osnr.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/extension/safari/TabFS/TabFS.xcodeproj/xcuserdata/osnr.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist index 3fadf29..3f0b7de 100644 --- a/extension/safari/TabFS/TabFS.xcodeproj/xcuserdata/osnr.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist +++ b/extension/safari/TabFS/TabFS.xcodeproj/xcuserdata/osnr.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist @@ -8,9 +8,57 @@ BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint"> + + + + + + + + + + + + - + - + + @@ -66,7 +67,7 @@ - + @@ -97,18 +98,28 @@ - + - + - + - + + @@ -138,11 +149,13 @@ DQ + + diff --git a/extension/safari/TabFS/TabFS/ViewController.swift b/extension/safari/TabFS/TabFS/ViewController.swift index 98cc7a5..958de47 100644 --- a/extension/safari/TabFS/TabFS/ViewController.swift +++ b/extension/safari/TabFS/TabFS/ViewController.swift @@ -48,4 +48,7 @@ class ViewController: NSViewController { } } + @IBAction func startTabFSAndConnect(_ sender: Any) { +// FSProcessManager.start() + } }