diff --git a/Sources/AndroidBridge/AndroidBridge.swift b/Sources/AndroidBridge/AndroidBridge.swift index 07317f8..a3fe223 100644 --- a/Sources/AndroidBridge/AndroidBridge.swift +++ b/Sources/AndroidBridge/AndroidBridge.swift @@ -1,13 +1,22 @@ +// Copyright 2024 Skip +// // This is free software: you can redistribute and/or modify it // under the terms of the GNU Lesser General Public License 3.0 // as published by the Free Software Foundation https://fsf.org -import Foundation -#if canImport(AndroidNative) -import AndroidNative -#else -import OSLog -#endif +//import Foundation +import SkipBridge -fileprivate let logger: Logger = Logger(subsystem: "AndroidBridge", category: "AndroidSwiftBridge") +// Current limitations on Roboelectric testing require us to go through a compiled wrapper in order to perform our +// tests of bridging Kotlin to Swift. + +// SKIP @BridgeToKotlin +func testSupport_isSkipMode() -> Int32 { + isSkipMode() +} + +// SKIP @BridgeToKotlin +func testSupport_getAndroidContext() -> AndroidContext! { + AndroidContext.shared +} diff --git a/Sources/AndroidBridge/Kotlin/AndroidKotlinBridge.swift b/Sources/AndroidBridge/Kotlin/AndroidKotlinBridge.swift index 9c10957..2d6c698 100644 --- a/Sources/AndroidBridge/Kotlin/AndroidKotlinBridge.swift +++ b/Sources/AndroidBridge/Kotlin/AndroidKotlinBridge.swift @@ -1,7 +1,27 @@ +// Copyright 2024 Skip +// +// This is free software: you can redistribute and/or modify it +// under the terms of the GNU Lesser General Public License 3.0 +// as published by the Free Software Foundation https://fsf.org + import Foundation -import OSLog +//#if canImport(AndroidNative) +//@_exported import AndroidNative +//#elseif canImport(OSLog) +//@_exported import OSLog +//#endif +// +//fileprivate let logger: Logger = Logger(subsystem: "AndroidBridge", category: "AndroidKotlinBridge") + -fileprivate let logger: Logger = Logger(subsystem: "AndroidBridge", category: "AndroidKotlinBridge") +// SKIP @BridgeToSwift +func isSkipMode() -> Int32 { + #if SKIP + return 1 + #else + return 0 + #endif +} // SKIP @BridgeToSwift func getJavaSystemProperty(_ name: String) -> String? { @@ -10,20 +30,51 @@ func getJavaSystemProperty(_ name: String) -> String? { #else return nil #endif -} +} + +// SKIP @BridgeToSwift +public func getAndroidContext() -> AndroidContext? { + //logger.warning("### getAndroidContext invoked") + #if SKIP + return AndroidContext(context: ProcessInfo.processInfo.androidContext) + #else + //fatalError("### getAndroidContext should only be called through Kotlin") + return nil + #endif +} // SKIP @BridgeToSwift public class AndroidContext { #if !SKIP /// In non-Skip environments, AndroidContext is nil - public static let shared: AndroidContext? = nil + public static let shared: AndroidContext! = nil #else - public static let shared: AndroidContext? = AndroidContext(context: ProcessInfo.processInfo.androidContext) + public static let shared: AndroidContext = AndroidContext(context: ProcessInfo.processInfo.androidContext) private let context: android.content.Context - private init(context: android.content.Context) { + fileprivate init(context: android.content.Context) { self.context = context } #endif + + /// Returns the absolute path to the directory on the filesystem where files created with openFileOutput(String, int) are stored. + /// + /// The returned path may change over time if the calling app is moved to an adopted storage device, so only relative paths should be persisted. + public var filesDir: String { + #if !SKIP + fatalError("unbridged invocation") + #else + self.context.getFilesDir().getAbsolutePath() + #endif + } + + /// Returns the absolute path to the application specific cache directory on the filesystem. + public var cacheDir: String { + #if !SKIP + fatalError("unbridged invocation") + #else + self.context.getCacheDir().getAbsolutePath() + #endif + } } diff --git a/Sources/AndroidBridge/Skip/skip.yml b/Sources/AndroidBridge/Skip/skip.yml index a2c7824..39298a8 100644 --- a/Sources/AndroidBridge/Skip/skip.yml +++ b/Sources/AndroidBridge/Skip/skip.yml @@ -1,4 +1,4 @@ # Configuration file for https://skip.tools project skip: - mode: swift + mode: 'swift' diff --git a/Tests/AndroidBridgeTests/AndroidBridgeTests.swift b/Tests/AndroidBridgeTests/AndroidBridgeTests.swift index 36dccbb..7a64628 100644 --- a/Tests/AndroidBridgeTests/AndroidBridgeTests.swift +++ b/Tests/AndroidBridgeTests/AndroidBridgeTests.swift @@ -1,3 +1,5 @@ +// Copyright 2024 Skip +// // This is free software: you can redistribute and/or modify it // under the terms of the GNU Lesser General Public License 3.0 // as published by the Free Software Foundation https://fsf.org @@ -19,11 +21,22 @@ final class AndroidBridgeTests: XCTestCase { } func testAndroidBridge() throws { - logger.log("running testSkipAndroidBridge") + let mode = testSupport_isSkipMode() #if SKIP - XCTAssertNotNil(AndroidContext.shared) + XCTAssertEqual(1, mode, "@BridgeToSwift should be transpiled") + #else + XCTAssertEqual(0, mode, "@BridgeToSwift should NOT be transpiled") + #endif + + logger.log("running testSkipAndroidBridge") + let context = testSupport_getAndroidContext() + #if !SKIP + XCTAssertNil(context) #else - XCTAssertNil(AndroidContext.shared) + XCTAssertNotNil(ProcessInfo.processInfo.androidContext, "ProcessInfo.processInfo.androidContext was nil") + XCTAssertNotNil(context, "bridged context was nil") + XCTAssertEqual("/data/user/0/android.bridge.test/files", context.filesDir) + XCTAssertEqual("/data/user/0/android.bridge.test/cache", context.cacheDir) #endif } } diff --git a/Tests/AndroidBridgeTests/XCSkipTests.swift b/Tests/AndroidBridgeTests/XCSkipTests.swift index 44bdc43..20644f5 100644 --- a/Tests/AndroidBridgeTests/XCSkipTests.swift +++ b/Tests/AndroidBridgeTests/XCSkipTests.swift @@ -1,3 +1,5 @@ +// Copyright 2024 Skip +// // This is free software: you can redistribute and/or modify it // under the terms of the GNU Lesser General Public License 3.0 // as published by the Free Software Foundation https://fsf.org