summaryrefslogtreecommitdiff
path: root/extension/safari
diff options
context:
space:
mode:
Diffstat (limited to 'extension/safari')
-rw-r--r--extension/safari/TabFS/TabFS Extension/SafariWebExtensionHandler.swift21
-rw-r--r--extension/safari/TabFS/TabFS.xcodeproj/project.xcworkspace/xcuserdata/osnr.xcuserdatad/UserInterfaceState.xcuserstatebin61786 -> 61421 bytes
-rw-r--r--extension/safari/TabFS/TabFSService/TabFSService.swift14
-rw-r--r--extension/safari/TabFS/TabFSService/TabFSServiceProtocols.swift2
4 files changed, 24 insertions, 13 deletions
diff --git a/extension/safari/TabFS/TabFS Extension/SafariWebExtensionHandler.swift b/extension/safari/TabFS/TabFS Extension/SafariWebExtensionHandler.swift
index d3b6843..fbe9538 100644
--- a/extension/safari/TabFS/TabFS Extension/SafariWebExtensionHandler.swift
+++ b/extension/safari/TabFS/TabFS Extension/SafariWebExtensionHandler.swift
@@ -18,23 +18,34 @@ class SafariWebExtensionHandler: NSObject, NSExtensionRequestHandling {
guard message["op"] as! String == "safari_did_connect" else { return }
// The XPC service is a subprocess that lives outside the macOS App Sandbox.
+ // (Safari extension native code, including this file, has to live in the sandbox.)
// It can do forbidden things like spawn tabfs filesystem and set up WebSocket server.
+ // We only use one native message to bootstrap the XPC service, then do all communications
+ // to that service (which in turn talks to tabfs.c) over WebSocket instead.
+ // (Safari makes doing native messaging quite painful, so we try to avoid it.
+ // It forces the browser to pop to front if you message Safari in the obvious way,
+ // for instance: https://developer.apple.com/forums/thread/122232
+ // And with the WebSocket, the XPC service can talk straight to background.js, whereas
+ // native messaging would require us here to sit in the middle.)
+
let connection = NSXPCConnection(serviceName: "com.rsnous.TabFSService")
connection.remoteObjectInterface = NSXPCInterface(with: TabFSServiceProtocol.self)
connection.resume()
let service = connection.remoteObjectProxyWithErrorHandler { error in
- os_log(.default, "Received error: %{public}@", error as! CVarArg)
+ os_log(.default, "Received error: %{public}@", error as CVarArg)
} as? TabFSServiceProtocol
- // need this one XPC call to actually initialize the service
- service?.upperCaseString("hello XPC") { response in
- os_log(.default, "Response from XPC service: %{public}@", response)
+ // Need this one XPC call to actually initialize the service.
+ service?.start() {
+ os_log(.default, "Response from XPC service")
// FIXME: report port back?
let response = NSExtensionItem()
- response.userInfo = [ "message": [ "aResponse to": "moop" ] ]
+ response.userInfo = [ "message": "alive" ]
+ // This response (over native messaging) prompts background.js to
+ // connect to the WebSocket server that the XPC service should now be running.
context.completeRequest(returningItems: [response]) { (what) in
print(what)
}
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 78ca235..7b7b1d3 100644
--- 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
Binary files differ
diff --git a/extension/safari/TabFS/TabFSService/TabFSService.swift b/extension/safari/TabFS/TabFSService/TabFSService.swift
index 85b29f3..86c39f8 100644
--- a/extension/safari/TabFS/TabFSService/TabFSService.swift
+++ b/extension/safari/TabFS/TabFSService/TabFSService.swift
@@ -67,7 +67,7 @@ class TabFSService: NSObject, TabFSServiceProtocol {
let context = NWConnection.ContentContext(identifier: "context", metadata: [metaData])
conn.send(content: req, contentContext: context, completion: .contentProcessed({ err in
if err != nil {
- os_log(.default, "req %{public}@ error: %{public}@", String(data: req, encoding: .utf8) as! CVarArg, err!.debugDescription as CVarArg)
+ os_log(.default, "req %{public}@ error: %{public}@", String(data: req, encoding: .utf8)!, err!.debugDescription as CVarArg)
// FIXME: ERROR
}
}))
@@ -81,6 +81,7 @@ class TabFSService: NSObject, TabFSServiceProtocol {
return
}
+ // Send the response back to tabfs.c.
self.fsInput.write(withUnsafeBytes(of: UInt32(resp.count)) { Data($0) })
self.fsInput.write(resp)
read()
@@ -89,15 +90,14 @@ class TabFSService: NSObject, TabFSServiceProtocol {
read()
}
- // split new thread
DispatchQueue.global(qos: .default).async {
while true {
- // read from them
+ // Blocking read from the tabfs process.
let length = self.fsOutput.readData(ofLength: 4).withUnsafeBytes { $0.load(as: UInt32.self) }
let req = self.fsOutput.readData(ofLength: Int(length))
- // send to other side of WEBSOCKET
if let handleRequest = handleRequest {
+ // Send the request over the WebSocket connection to background.js in browser.
handleRequest(req)
} else {
// FIXME: ERROR
@@ -107,9 +107,9 @@ class TabFSService: NSObject, TabFSServiceProtocol {
// FIXME: disable auto termination
}
- func upperCaseString(_ string: String, withReply reply: @escaping (String) -> Void) {
- let response = string.uppercased()
- reply(response)
+ func start(withReply reply: @escaping () -> Void) {
+ // This XPC call is enough to just force the XPC service to be started.
+ reply()
}
}
diff --git a/extension/safari/TabFS/TabFSService/TabFSServiceProtocols.swift b/extension/safari/TabFS/TabFSService/TabFSServiceProtocols.swift
index 8aedd87..4dd6e77 100644
--- a/extension/safari/TabFS/TabFSService/TabFSServiceProtocols.swift
+++ b/extension/safari/TabFS/TabFSService/TabFSServiceProtocols.swift
@@ -8,5 +8,5 @@
import Foundation
@objc public protocol TabFSServiceProtocol {
- func upperCaseString(_ string: String, withReply reply: @escaping (String) -> Void)
+ func start(withReply reply: @escaping () -> Void)
}