Skip to content

Commit 9e5bd28

Browse files
committed
Add Permission.Error
1 parent 67fe2d8 commit 9e5bd28

1 file changed

Lines changed: 53 additions & 20 deletions

File tree

Sources/AndroidManifest/PermissionCheck.swift

Lines changed: 53 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,34 @@ import Darwin
1313
#elseif canImport(Glibc)
1414
import Glibc
1515
#endif
16-
import SystemPackage
1716

1817
public extension Permission {
1918

20-
/// Result of `APermissionManager_checkPermission`.
21-
enum CheckStatus: Sendable, Equatable {
19+
/// Permission State
20+
enum CheckStatus: Int32, Sendable, Equatable {
21+
2222
/// Permission is granted (`0`).
23-
case granted
23+
case granted = 0
24+
2425
/// Permission is denied (`-1`).
25-
case denied
26-
/// Any other platform-specific status code.
27-
case unknown(Int32)
26+
case denied = -1
27+
}
28+
29+
enum Error: Int32, Swift.Error {
30+
31+
/**
32+
This is returned if the permission check encountered an unspecified error.
33+
34+
The output result is unmodified.
35+
*/
36+
case unknown = -1
37+
38+
/**
39+
This is returned if the permission check failed because the service is unavailable.
40+
41+
The output result is unmodified.
42+
*/
43+
case serviceUnavailable = -2
2844
}
2945
}
3046

@@ -40,27 +56,44 @@ public extension Permission {
4056
func check(
4157
pid: pid_t = getpid(),
4258
uid: uid_t = getuid()
43-
) -> CheckStatus {
44-
let result: Int32
59+
) throws(Permission.Error) -> CheckStatus {
60+
try _check(pid: pid, uid: uid).get()
61+
}
62+
63+
/// Checks this permission for a specific process/user pair using
64+
/// `APermissionManager_checkPermission`.
65+
///
66+
/// - Parameters:
67+
/// - pid: Process ID to evaluate. Defaults to the current process ID.
68+
/// - uid: User ID to evaluate. Defaults to the current user ID.
69+
/// - Returns: Permission check status.
70+
internal func _check(
71+
pid: pid_t = getpid(),
72+
uid: uid_t = getuid()
73+
) -> Result<CheckStatus, Error> {
74+
var result: Int32 = -1
75+
let returnCode: Int32
4576
#if os(Android)
46-
result = rawValue.withCString {
47-
APermissionManager_checkPermission($0, pid, uid)
77+
returnCode = rawValue.withCString {
78+
APermissionManager_checkPermission($0, pid, uid, &result)
4879
}
4980
#else
50-
result = -1
81+
returnCode = -1
5182
#endif
52-
switch result {
53-
case 0:
54-
return .granted
55-
case -1:
56-
return .denied
57-
default:
58-
return .unknown(result)
83+
guard returnCode != 0, let status = CheckStatus(rawValue: result) else {
84+
return .failure(.init(rawValue: returnCode) ?? .unknown)
5985
}
86+
return .success(status)
6087
}
6188

6289
/// Returns `true` when this permission is granted for the current process.
6390
var isGranted: Bool {
64-
check() == .granted
91+
let status = _check()
92+
switch status {
93+
case .success(.granted):
94+
return true
95+
default:
96+
return false
97+
}
6598
}
6699
}

0 commit comments

Comments
 (0)