Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix issue of call connection callback multiple times #92

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 17 additions & 12 deletions poolakey/src/main/java/ir/cafebazaar/poolakey/BillingConnection.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ package ir.cafebazaar.poolakey

import android.app.Activity
import android.content.Context
import android.os.Build
import android.os.Build.VERSION.SDK_INT
import android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
import androidx.activity.result.ActivityResult
import androidx.activity.result.ActivityResultRegistry
Expand Down Expand Up @@ -60,17 +58,24 @@ internal class BillingConnection(
queryFunction
)

val canConnect = serviceCommunicator.startConnection(context, requireNotNull(callback))
val serviceConnectRequestResult =
serviceCommunicator.startConnection(context, requireNotNull(callback))

billingCommunicator = if (canConnect) {
serviceCommunicator
} else {
receiverConnection.startConnection(
context,
requireNotNull(callback)
)
billingCommunicator = when {
serviceConnectRequestResult.canConnect -> serviceCommunicator
serviceConnectRequestResult.canUseFallback -> {
val receiverConnectRequestResult = receiverConnection.startConnection(
context,
requireNotNull(callback)
)
if (receiverConnectRequestResult.canConnect) {
receiverConnection
} else {
null
}
}

receiverConnection
else -> null
}
return requireNotNull(callback)
}
Expand All @@ -85,7 +90,7 @@ internal class BillingConnection(
onActivityResult(it, purchaseCallback)
}.build()

purchaseRequest.cutoutModeIsShortEdges = if (SDK_INT >= Build.VERSION_CODES.P) {
purchaseRequest.cutoutModeIsShortEdges = if (isSdkPieAndUp()) {
(context as? Activity)
?.window
?.attributes
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package ir.cafebazaar.poolakey

internal data class ConnectionRequestResult(
val canConnect: Boolean,
val canUseFallback: Boolean = true
)
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package ir.cafebazaar.poolakey

import android.content.Context
import android.content.pm.PackageInfo
import android.os.Build

internal fun getPackageInfo(context: Context, packageName: String): PackageInfo? = try {
val packageManager = context.packageManager
Expand All @@ -12,9 +13,13 @@ internal fun getPackageInfo(context: Context, packageName: String): PackageInfo?

@Suppress("DEPRECATION")
internal fun sdkAwareVersionCode(packageInfo: PackageInfo): Long {
return if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.P) {
return if (isSdkPieAndUp()) {
packageInfo.longVersionCode
} else {
packageInfo.versionCode.toLong()
}
}
}

internal fun isSdkNougatAndUp() = Build.VERSION.SDK_INT >= Build.VERSION_CODES.N

internal fun isSdkPieAndUp() = Build.VERSION.SDK_INT >= Build.VERSION_CODES.P
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package ir.cafebazaar.poolakey.billing.connection

import android.content.Context
import ir.cafebazaar.poolakey.ConnectionRequestResult
import ir.cafebazaar.poolakey.PurchaseType
import ir.cafebazaar.poolakey.PaymentLauncher
import ir.cafebazaar.poolakey.billing.skudetail.SkuDetailFunctionRequest
Expand All @@ -18,7 +19,7 @@ internal interface BillingConnectionCommunicator {
fun startConnection(
context: Context,
callback: ConnectionCallback
): Boolean
): ConnectionRequestResult

fun consume(
purchaseToken: String,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package ir.cafebazaar.poolakey.billing.connection
import android.content.Context
import android.content.Intent
import android.os.Bundle
import ir.cafebazaar.poolakey.ConnectionRequestResult
import ir.cafebazaar.poolakey.PurchaseType
import ir.cafebazaar.poolakey.PaymentLauncher
import ir.cafebazaar.poolakey.billing.Feature
Expand All @@ -27,6 +28,7 @@ import ir.cafebazaar.poolakey.constant.BazaarIntent
import ir.cafebazaar.poolakey.constant.BazaarIntent.REQUEST_SKU_DETAILS_LIST
import ir.cafebazaar.poolakey.constant.Billing
import ir.cafebazaar.poolakey.constant.Const.BAZAAR_PACKAGE_NAME
import ir.cafebazaar.poolakey.exception.BazaarNotFoundException
import ir.cafebazaar.poolakey.exception.BazaarNotSupportedException
import ir.cafebazaar.poolakey.exception.ConsumeFailedException
import ir.cafebazaar.poolakey.exception.DisconnectException
Expand Down Expand Up @@ -64,33 +66,36 @@ internal class ReceiverBillingConnection(

private var purchaseWeakReference: WeakReference<PurchaseWeakHolder>? = null

override fun startConnection(context: Context, callback: ConnectionCallback): Boolean {
override fun startConnection(
context: Context,
callback: ConnectionCallback
): ConnectionRequestResult {
connectionCallbackReference = WeakReference(callback)
contextReference = WeakReference(context)

if (!Security.verifyBazaarIsInstalled(context)) {
return false
}
if (Security.verifyBazaarIsInstalled(context)) {
bazaarVersionCode = getPackageInfo(context, BAZAAR_PACKAGE_NAME)?.let {
sdkAwareVersionCode(it)
} ?: 0L

return when {
canConnectWithReceiverComponent() -> {
createReceiverConnection()
registerBroadcast()
isPurchaseTypeSupported()
ConnectionRequestResult(true)
}

bazaarVersionCode = getPackageInfo(context, BAZAAR_PACKAGE_NAME)?.let {
sdkAwareVersionCode(it)
} ?: 0L
bazaarVersionCode > 0 -> {
callback.connectionFailed.invoke(BazaarNotSupportedException())
ConnectionRequestResult(canConnect = false, canUseFallback = false)
}

return when {
canConnectWithReceiverComponent() -> {
createReceiverConnection()
registerBroadcast()
isPurchaseTypeSupported()
true
}
bazaarVersionCode > 0 -> {
callback.connectionFailed.invoke(BazaarNotSupportedException())
false
}
else -> {
false
else -> ConnectionRequestResult(false)
}
}
callback.connectionFailed.invoke(BazaarNotFoundException())
return ConnectionRequestResult(canConnect = false, canUseFallback = false)
}

private fun canConnectWithReceiverComponent(): Boolean {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ import android.content.Intent
import android.content.IntentSender
import android.content.ServiceConnection
import android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS
import android.os.Build
import android.os.Bundle
import android.os.IBinder
import android.os.RemoteException
import androidx.activity.result.IntentSenderRequest
import com.android.vending.billing.IInAppBillingService
import ir.cafebazaar.poolakey.ConnectionRequestResult
import ir.cafebazaar.poolakey.ConnectionState
import ir.cafebazaar.poolakey.PurchaseType
import ir.cafebazaar.poolakey.PaymentLauncher
Expand Down Expand Up @@ -40,6 +40,7 @@ import ir.cafebazaar.poolakey.exception.BazaarNotFoundException
import ir.cafebazaar.poolakey.exception.DisconnectException
import ir.cafebazaar.poolakey.exception.IAPNotSupportedException
import ir.cafebazaar.poolakey.exception.SubsNotSupportedException
import ir.cafebazaar.poolakey.isSdkNougatAndUp
import ir.cafebazaar.poolakey.request.PurchaseRequest
import ir.cafebazaar.poolakey.security.Security
import ir.cafebazaar.poolakey.takeIf
Expand All @@ -65,34 +66,33 @@ internal class ServiceBillingConnection(
private var callbackReference: WeakReference<ConnectionCallback>? = null
private var contextReference: WeakReference<Context>? = null

override fun startConnection(context: Context, callback: ConnectionCallback): Boolean {
override fun startConnection(
context: Context,
callback: ConnectionCallback
): ConnectionRequestResult {
callbackReference = WeakReference(callback)
contextReference = WeakReference(context)

return Intent(BILLING_SERVICE_ACTION).apply {
`package` = BAZAAR_PACKAGE_NAME
setClassName(BAZAAR_PACKAGE_NAME, BAZAAR_PAYMENT_SERVICE_CLASS_NAME)
}
.takeIf(
if (Security.verifyBazaarIsInstalled(context)) {
Intent(BILLING_SERVICE_ACTION).apply {
`package` = BAZAAR_PACKAGE_NAME
setClassName(BAZAAR_PACKAGE_NAME, BAZAAR_PAYMENT_SERVICE_CLASS_NAME)
}.takeIf(
thisIsTrue = ::isServiceAvailable,
andIfNot = {
callback.connectionFailed.invoke(BazaarNotFoundException())
}
)?.takeIf(
thisIsTrue = {
Security.verifyBazaarIsInstalled(context)
},
andIfNot = {
callback.connectionFailed.invoke(BazaarNotFoundException())
return ConnectionRequestResult(canConnect = false, canUseFallback = false)
}
)?.let {
try {
context.bindService(it, this, Context.BIND_AUTO_CREATE)
return try {
ConnectionRequestResult(context.bindService(it, this, Context.BIND_AUTO_CREATE))
} catch (e: SecurityException) {
callback.connectionFailed.invoke(e)
false
ConnectionRequestResult(false)
}
} ?: false
}
}
callback.connectionFailed.invoke(BazaarNotFoundException())
return ConnectionRequestResult(canConnect = false, canUseFallback = false)
}

override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
Expand Down Expand Up @@ -288,7 +288,7 @@ internal class ServiceBillingConnection(
}

private fun isServiceAvailableInDeepSleep(intent: Intent): Boolean {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.N &&
return isSdkNougatAndUp() &&
context.packageManager
.queryIntentServices(intent, MATCH_DISABLED_COMPONENTS)
.isNotEmpty()
Expand Down