<lambda>null1 package expo.modules.notifications.permissions
2
3 import android.Manifest
4 import android.app.NotificationManager
5 import android.content.Context
6 import android.os.Build
7 import androidx.annotation.RequiresApi
8 import androidx.core.app.NotificationManagerCompat
9 import androidx.core.os.bundleOf
10 import expo.modules.core.arguments.ReadableArguments
11 import expo.modules.interfaces.permissions.Permissions
12 import expo.modules.interfaces.permissions.PermissionsResponse
13 import expo.modules.interfaces.permissions.PermissionsStatus
14 import expo.modules.kotlin.Promise
15 import expo.modules.kotlin.exception.Exceptions
16 import expo.modules.kotlin.modules.Module
17 import expo.modules.kotlin.modules.ModuleDefinition
18 import expo.modules.notifications.ModuleNotFoundException
19
20 private const val ANDROID_RESPONSE_KEY = "android"
21 private const val IMPORTANCE_KEY = "importance"
22 private const val INTERRUPTION_FILTER_KEY = "interruptionFilter"
23 private val PERMISSIONS: Array<String> = arrayOf(Manifest.permission.POST_NOTIFICATIONS)
24
25 class NotificationPermissionsModule : Module() {
26 private val permissions: Permissions
27 get() = appContext.permissions ?: throw ModuleNotFoundException(Permissions::class)
28
29 private val context: Context
30 get() = appContext.reactContext ?: throw Exceptions.ReactContextLost()
31
32 override fun definition() = ModuleDefinition {
33 Name("ExpoNotificationPermissionsModule")
34
35 AsyncFunction("getPermissionsAsync") { promise: Promise ->
36 if (context.applicationContext.applicationInfo.targetSdkVersion >= 33 && Build.VERSION.SDK_INT >= 33) {
37 getPermissionsWithPromiseImplApi33(promise)
38 } else {
39 getPermissionsWithPromiseImplClassic(promise)
40 }
41 }
42
43 AsyncFunction("requestPermissionsAsync") { _: ReadableArguments?, promise: Promise ->
44 if (context.applicationContext.applicationInfo.targetSdkVersion >= 33 && Build.VERSION.SDK_INT >= 33) {
45 requestPermissionsWithPromiseImplApi33(promise)
46 } else {
47 getPermissionsWithPromiseImplClassic(promise)
48 }
49 }
50 }
51
52 @RequiresApi(33)
53 private fun getPermissionsWithPromiseImplApi33(promise: Promise) {
54 permissions.getPermissions(
55 { permissionsMap: Map<String, PermissionsResponse> ->
56 val managerCompat = NotificationManagerCompat.from(context)
57 val areEnabled = managerCompat.areNotificationsEnabled()
58 val platformBundle = bundleOf(
59 IMPORTANCE_KEY to managerCompat.importance,
60 ).apply {
61 val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as? NotificationManager
62 if (notificationManager != null) {
63 putInt(INTERRUPTION_FILTER_KEY, notificationManager.currentInterruptionFilter)
64 }
65 }
66
67 val areAllGranted = permissionsMap.all { (_, response) -> response.status == PermissionsStatus.GRANTED }
68 val areAllDenied = permissionsMap.all { (_, response) -> response.status == PermissionsStatus.DENIED }
69 val canAskAgain = permissionsMap.all { (_, response) -> response.canAskAgain }
70 val status = when {
71 areAllDenied -> PermissionsStatus.DENIED.status
72 !areEnabled -> PermissionsStatus.DENIED.status
73 areAllGranted -> PermissionsStatus.GRANTED.status
74 else -> PermissionsStatus.UNDETERMINED.status
75 }
76
77 promise.resolve(
78 bundleOf(
79 PermissionsResponse.EXPIRES_KEY to PermissionsResponse.PERMISSION_EXPIRES_NEVER,
80 PermissionsResponse.STATUS_KEY to status,
81 PermissionsResponse.CAN_ASK_AGAIN_KEY to canAskAgain,
82 PermissionsResponse.GRANTED_KEY to areAllGranted,
83 ANDROID_RESPONSE_KEY to platformBundle,
84 )
85 )
86 },
87 *PERMISSIONS
88 )
89 }
90
91 private fun getPermissionsWithPromiseImplClassic(promise: Promise) {
92 val managerCompat = NotificationManagerCompat.from(context)
93 val areEnabled = managerCompat.areNotificationsEnabled()
94 val status = if (areEnabled) PermissionsStatus.GRANTED else PermissionsStatus.DENIED
95 val platformBundle = bundleOf(
96 IMPORTANCE_KEY to managerCompat.importance,
97 ).apply {
98 val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as? NotificationManager
99 if (notificationManager != null) {
100 putInt(INTERRUPTION_FILTER_KEY, notificationManager.currentInterruptionFilter)
101 }
102 }
103
104 promise.resolve(
105 bundleOf(
106 PermissionsResponse.EXPIRES_KEY to PermissionsResponse.PERMISSION_EXPIRES_NEVER,
107 PermissionsResponse.STATUS_KEY to status.status,
108 PermissionsResponse.CAN_ASK_AGAIN_KEY to areEnabled,
109 PermissionsResponse.GRANTED_KEY to (status == PermissionsStatus.GRANTED),
110 ANDROID_RESPONSE_KEY to platformBundle,
111 )
112 )
113 }
114
115 @RequiresApi(33)
116 private fun requestPermissionsWithPromiseImplApi33(promise: Promise) {
117 permissions.askForPermissions(
118 {
119 getPermissionsWithPromiseImplApi33(promise)
120 },
121 *PERMISSIONS
122 )
123 }
124 }
125