react-native-iap 12.4.14 → 12.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,33 @@
1
+ package com.dooboolab.RNIap
2
+
3
+ import android.app.Activity
4
+ import android.util.Log
5
+ import com.amazon.device.iap.PurchasingService
6
+
7
+ /**
8
+ * In order of the IAP process to show correctly, AmazonPurchasingService must be registered on Activity.onCreate
9
+ * registering it in on Application.onCreate will not throw an error but it will now show the Native purchasing screen
10
+ */
11
+ class RNIapActivityListener {
12
+ companion object {
13
+ @JvmStatic
14
+ var hasListener = false
15
+
16
+ @JvmStatic
17
+ var amazonListener: RNIapAmazonListener? = null
18
+
19
+ @JvmStatic
20
+ fun registerActivity(activity: Activity) {
21
+ amazonListener = RNIapAmazonListener(null, null)
22
+ try {
23
+ PurchasingService.registerListener(activity, amazonListener)
24
+ hasListener = true
25
+ // Prefetch user and purchases as per Amazon SDK documentation:
26
+ PurchasingService.getUserData()
27
+ PurchasingService.getPurchaseUpdates(false)
28
+ } catch (e: Exception) {
29
+ Log.e(RNIapAmazonModule.TAG, "Error initializing Amazon appstore sdk", e)
30
+ }
31
+ }
32
+ }
33
+ }
@@ -19,8 +19,8 @@ val ProductType.typeString: String
19
19
  get() = if (this == ProductType.ENTITLED || this == ProductType.CONSUMABLE) "inapp" else "subs"
20
20
 
21
21
  class RNIapAmazonListener(
22
- private val eventSender: EventSender?,
23
- private val purchasingService: PurchasingServiceProxy?
22
+ var eventSender: EventSender?,
23
+ var purchasingService: PurchasingServiceProxy?
24
24
  ) : PurchasingListener {
25
25
 
26
26
  override fun onProductDataResponse(response: ProductDataResponse) {
@@ -1,11 +1,8 @@
1
1
  package com.dooboolab.RNIap
2
2
 
3
- import android.os.Handler
4
- import android.os.Looper
5
3
  import android.util.Log
6
4
  import com.amazon.device.drm.LicensingService
7
5
  import com.amazon.device.drm.model.LicenseResponse
8
- import com.amazon.device.iap.PurchasingListener
9
6
  import com.amazon.device.iap.model.FulfillmentResult
10
7
  import com.facebook.react.bridge.LifecycleEventListener
11
8
  import com.facebook.react.bridge.Promise
@@ -19,44 +16,35 @@ import com.facebook.react.modules.core.DeviceEventManagerModule
19
16
 
20
17
  @ReactModule(name = RNIapAmazonModule.TAG)
21
18
  class RNIapAmazonModule(
22
- reactContext: ReactApplicationContext,
19
+ private val reactContext: ReactApplicationContext,
23
20
  private val purchasingService: PurchasingServiceProxy = PurchasingServiceProxyAmazonImpl(),
24
- private val handler: Handler = Handler(Looper.getMainLooper()),
25
- private val amazonListener: PurchasingListener = RNIapAmazonListener(
26
- object : EventSender {
27
- private val rctDeviceEventEmitter = reactContext
28
- .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
29
-
30
- override fun sendEvent(eventName: String, params: WritableMap?) {
31
- rctDeviceEventEmitter
32
- .emit(eventName, params)
33
- }
34
- },
35
- purchasingService
36
- )
21
+ private var eventSender: EventSender? = null
37
22
  ) :
38
23
  ReactContextBaseJavaModule(reactContext) {
39
- var hasListener = false
40
24
  override fun getName(): String {
41
25
  return TAG
42
26
  }
43
27
 
44
28
  @ReactMethod
45
29
  fun initConnection(promise: Promise) {
46
- val context = reactApplicationContext
47
-
48
- handler.postDelayed({
49
- try {
50
- purchasingService.registerListener(context.applicationContext, amazonListener)
51
- hasListener = true
52
- // Prefetch user and purchases as per Amazon SDK documentation:
53
- purchasingService.getUserData()
54
- purchasingService.getPurchaseUpdates(false)
55
- promise.safeResolve(true)
56
- } catch (e: Exception) {
57
- promise.safeReject("Error initializing Amazon appstore sdk", e)
30
+ if (RNIapActivityListener.amazonListener == null) {
31
+ promise.safeReject(PromiseUtils.E_DEVELOPER_ERROR, Exception("RNIapActivityListener is not registered in your MainActivity.onCreate"))
32
+ return
33
+ }
34
+ if (eventSender == null) {
35
+ eventSender = object : EventSender {
36
+ private val rctDeviceEventEmitter = reactContext
37
+ .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
38
+
39
+ override fun sendEvent(eventName: String, params: WritableMap?) {
40
+ rctDeviceEventEmitter
41
+ .emit(eventName, params)
42
+ }
58
43
  }
59
- }, 0L)
44
+ }
45
+ RNIapActivityListener.amazonListener?.eventSender = eventSender
46
+ RNIapActivityListener.amazonListener?.purchasingService = purchasingService
47
+ promise.resolve(true)
60
48
  }
61
49
 
62
50
  @ReactMethod
@@ -101,7 +89,7 @@ class RNIapAmazonModule(
101
89
  @ReactMethod
102
90
  fun endConnection(promise: Promise) {
103
91
  PromiseUtils.rejectAllPendingPromises()
104
- hasListener = false
92
+ RNIapActivityListener.hasListener = false
105
93
  promise.resolve(true)
106
94
  }
107
95
 
@@ -204,7 +192,7 @@ class RNIapAmazonModule(
204
192
  * We should fetch updates on resume
205
193
  */
206
194
  override fun onHostResume() {
207
- if (hasListener) {
195
+ if (RNIapActivityListener.hasListener) {
208
196
  purchasingService.getUserData()
209
197
  purchasingService.getPurchaseUpdates(false)
210
198
  }
@@ -0,0 +1,15 @@
1
+ package com.dooboolab.RNIap
2
+
3
+ import android.app.Activity
4
+
5
+ /**
6
+ * Currently only needed for Amazon IAP
7
+ */
8
+ class RNIapActivityListener {
9
+ companion object {
10
+ @JvmStatic
11
+ fun registerActivity(activity: Activity) {
12
+ // No op
13
+ }
14
+ }
15
+ }
@@ -1,6 +1,5 @@
1
1
  package com.dooboolab.RNIap
2
2
 
3
- import android.os.Handler
4
3
  import com.amazon.device.iap.model.PurchaseResponse
5
4
  import com.amazon.device.iap.model.Receipt
6
5
  import com.amazon.device.iap.model.RequestId
@@ -21,6 +20,7 @@ import io.mockk.slot
21
20
  import io.mockk.spyk
22
21
  import io.mockk.verify
23
22
  import org.junit.Assert.assertEquals
23
+ import org.junit.Assert.assertNotNull
24
24
  import org.junit.Before
25
25
  import org.junit.Test
26
26
  import java.util.*
@@ -33,9 +33,6 @@ class RNIapAmazonModuleTest {
33
33
  @RelaxedMockK
34
34
  lateinit var purchasingServiceProxy: PurchasingServiceProxy
35
35
 
36
- @MockK
37
- lateinit var mainThreadHandler: Handler
38
-
39
36
  @MockK
40
37
  lateinit var eventSender: EventSender
41
38
 
@@ -47,20 +44,35 @@ class RNIapAmazonModuleTest {
47
44
  fun setUp() {
48
45
  MockKAnnotations.init(this, relaxUnitFun = true)
49
46
  listener = spyk(RNIapAmazonListener(eventSender, purchasingServiceProxy))
50
- module = RNIapAmazonModule(context, purchasingServiceProxy, mainThreadHandler, listener)
47
+ module = RNIapAmazonModule(context, purchasingServiceProxy, eventSender)
51
48
  }
52
49
 
53
50
  @Test
54
- fun `initConnection should resolve to true`() {
51
+ fun `initConnection should resolve to true if RNIapActivityListener is configured`() {
55
52
  every { context.applicationContext } returns mockk()
56
53
 
57
54
  val promise = mockk<Promise>(relaxed = true)
58
- val slot = slot<Runnable>()
59
- every { mainThreadHandler.postDelayed(capture(slot), any()) } answers { slot.captured.run(); true }
60
- module.initConnection(promise)
55
+
61
56
  verify(exactly = 0) { promise.reject(any(), any<String>()) }
57
+
58
+ RNIapActivityListener.registerActivity(mockk())
59
+
60
+ module.initConnection(promise)
61
+ // should set eventSender and purchase service
62
+ assertNotNull(RNIapActivityListener.amazonListener?.purchasingService)
63
+ assertNotNull(RNIapActivityListener.amazonListener?.eventSender)
64
+
62
65
  verify { promise.resolve(true) }
63
- verify { purchasingServiceProxy.registerListener(any(), any()) }
66
+ }
67
+
68
+ @Test
69
+ fun `initConnection should reject if RNIapActivityListener is not configured`() {
70
+ every { context.applicationContext } returns mockk()
71
+
72
+ val promise = mockk<Promise>(relaxed = true)
73
+ module.initConnection(promise)
74
+ verify(exactly = 0) { promise.reject(any(), any<String>()) }
75
+ verify { promise.reject(PromiseUtils.E_DEVELOPER_ERROR, any(), any<Throwable>()) }
64
76
  }
65
77
 
66
78
  @Test
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-iap",
3
- "version": "12.4.14",
3
+ "version": "12.5.0",
4
4
  "description": "React Native In App Purchase Module.",
5
5
  "repository": "https://github.com/dooboolab/react-native-iap",
6
6
  "author": "dooboolab <support@dooboolab.com> (https://github.com/dooboolab)",