From feadf4f6c860bf67fdad43fa848162c6aa8702a9 Mon Sep 17 00:00:00 2001 From: Alsey Coleman Miller Date: Sat, 28 Feb 2026 10:43:12 -0500 Subject: [PATCH 1/3] Add availability annotations --- Sources/AndroidBinder/AndroidBinder.swift | 3 +++ Sources/AndroidBinder/Parcel.swift | 8 ++++++++ Sources/AndroidBinder/Status.swift | 6 +++++- Sources/AndroidOS/ParcelNDK.swift | 2 ++ 4 files changed, 18 insertions(+), 1 deletion(-) diff --git a/Sources/AndroidBinder/AndroidBinder.swift b/Sources/AndroidBinder/AndroidBinder.swift index 1508788..f4c3cca 100644 --- a/Sources/AndroidBinder/AndroidBinder.swift +++ b/Sources/AndroidBinder/AndroidBinder.swift @@ -111,9 +111,12 @@ public extension AndroidBinder { /** * Determine whether the current thread is currently executing an incoming transaction. * + * Available since API level 33. + * * \return true if the current thread is currently executing an incoming transaction, and false * otherwise. */ + @available(Android 33, *) static var isHandlingTransaction: Bool { AIBinder_isHandlingTransaction() } diff --git a/Sources/AndroidBinder/Parcel.swift b/Sources/AndroidBinder/Parcel.swift index 696aa7c..208e150 100644 --- a/Sources/AndroidBinder/Parcel.swift +++ b/Sources/AndroidBinder/Parcel.swift @@ -50,6 +50,7 @@ public extension Parcel { * * \return A parcel which is not related to any IBinder objects. */ + @available(Android 31, *) init() { self.handle = .create() } @@ -73,6 +74,7 @@ public extension Parcel { * * Available since API level 31. */ + @available(Android 31, *) var dataSize: Int { Int(handle.dataSize) } @@ -106,6 +108,7 @@ public extension Parcel { * * Available since API level 31. */ + @available(Android 31, *) func reset() throws(AndroidBinderError) { try handle.reset().get() } @@ -119,6 +122,7 @@ public extension Parcel { * \param start starting position in \p other (must be a value from getDataPosition). * \param size number of bytes to copy from \p other. */ + @available(Android 31, *) func appendContents(of other: borrowing Parcel, start: Int = 0, size: Int) throws(AndroidBinderError) { try handle.appendFrom(other.handle, start: Int32(start), size: Int32(size)).get() } @@ -602,6 +606,7 @@ internal extension Parcel.Handle { * * Available since API level 31. */ + @available(Android 31, *) static func create() -> Parcel.Handle { guard let pointer = AParcel_create() else { fatalError("Unable to initialize \(Self.self) \(#function)") @@ -637,6 +642,7 @@ internal extension Parcel.Handle { * * Available since API level 31. */ + @available(Android 31, *) var dataSize: Int32 { AParcel_getDataSize(pointer) } @@ -655,6 +661,7 @@ internal extension Parcel.Handle { * * Available since API level 31. */ + @available(Android 31, *) func reset() -> Result { AParcel_reset(pointer).mapError() } @@ -664,6 +671,7 @@ internal extension Parcel.Handle { * * Available since API level 31. */ + @available(Android 31, *) func appendFrom(_ from: Parcel.Handle, start: Int32, size: Int32) -> Result { AParcel_appendFrom(from.pointer, pointer, start, size).mapError() } diff --git a/Sources/AndroidBinder/Status.swift b/Sources/AndroidBinder/Status.swift index 2fac99c..e921b2b 100644 --- a/Sources/AndroidBinder/Status.swift +++ b/Sources/AndroidBinder/Status.swift @@ -121,6 +121,7 @@ public extension Status { extension Status { //: CustomStringConvertible, CustomDebugStringConvertible { /// Get human-readable description for debugging. + @available(Android 30, *) public var description: String { handle.withDescription { $0.description } } @@ -142,6 +143,7 @@ internal extension Status { internal extension Status { + @available(Android 30, *) struct Description: ~Copyable { let cString: UnsafePointer @@ -172,8 +174,9 @@ internal extension Status { } } +@available(Android 30, *) extension Status.Description { - + public var description: String { String(cString: cString) } @@ -290,6 +293,7 @@ internal extension Status.Handle { * * \return a description, must be deleted with AStatus_deleteDescription. */ + @available(Android 30, *) func withDescription(_ block: (borrowing Status.Description) -> T) -> T { let description = Status.Description(status: self) return block(description) diff --git a/Sources/AndroidOS/ParcelNDK.swift b/Sources/AndroidOS/ParcelNDK.swift index eb6caa9..5ac6804 100644 --- a/Sources/AndroidOS/ParcelNDK.swift +++ b/Sources/AndroidOS/ParcelNDK.swift @@ -24,6 +24,7 @@ public extension AndroidOS.Parcel { public extension AndroidOS.Parcel { /// Create a temporary NDK object and perform operatios on it. + @available(Android 30, *) func withNDK(_ body: (borrowing NDK) throws(E) -> Result) throws(E) -> Result where E: Error { let ndk = NDK.fromJava(javaThis, environment: javaEnvironment) return try body(ndk) @@ -46,6 +47,7 @@ internal extension AndroidBinder.Parcel { * will return null. This must be deleted with AParcel_delete. This does not take ownership of the * jobject and is only good for as long as the jobject is alive. */ + @available(Android 30, *) static func fromJava(_ javaObject: jobject, environment: JNIEnvironment) -> AndroidBinder.Parcel { guard let pointer = AParcel_fromJavaParcel(environment, javaObject) else { fatalError("Unable to initialize from Java object") From 949fa5a7bd30a93c7671598193b49593b18e15c6 Mon Sep 17 00:00:00 2001 From: Alsey Coleman Miller Date: Sat, 28 Feb 2026 10:43:43 -0500 Subject: [PATCH 2/3] Fix `AndroidBinderError.message` --- Sources/AndroidBinder/Error.swift | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Sources/AndroidBinder/Error.swift b/Sources/AndroidBinder/Error.swift index 03177a3..5c97440 100644 --- a/Sources/AndroidBinder/Error.swift +++ b/Sources/AndroidBinder/Error.swift @@ -36,8 +36,12 @@ public struct AndroidBinderError: Error { public extension AndroidBinderError { var message: String { - let status = Status(errorCode: errorCode) - return status.description + if #available(Android 30, *) { + let status = Status(errorCode: errorCode) + return status.description + } else { + return "Binder error (code: \(errorCode))" + } } } From f2e95354288380e8bd4c6537c6712a8dcee417fb Mon Sep 17 00:00:00 2001 From: Alsey Coleman Miller Date: Sat, 28 Feb 2026 10:44:18 -0500 Subject: [PATCH 3/3] Fix `AndroidBinder.init()` --- Sources/AndroidOS/IBinderNDK.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/AndroidOS/IBinderNDK.swift b/Sources/AndroidOS/IBinderNDK.swift index 3e2071a..98a89f0 100644 --- a/Sources/AndroidOS/IBinderNDK.swift +++ b/Sources/AndroidOS/IBinderNDK.swift @@ -56,7 +56,7 @@ internal extension AndroidBinder { * the Java object is of the wrong type, this will return null. */ convenience init(_ javaObject: jobject, environment: JNIEnvironment) { - guard let pointer = AParcel_fromJavaParcel(environment, javaObject) else { + guard let pointer = AIBinder_fromJavaBinder(environment, javaObject) else { fatalError("Unable to initialize from Java object") } self.init(pointer)