diff --git a/poolakey/src/main/java/ir/cafebazaar/poolakey/BillingConnection.kt b/poolakey/src/main/java/ir/cafebazaar/poolakey/BillingConnection.kt index e21c2f9..b253cc2 100644 --- a/poolakey/src/main/java/ir/cafebazaar/poolakey/BillingConnection.kt +++ b/poolakey/src/main/java/ir/cafebazaar/poolakey/BillingConnection.kt @@ -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 @@ -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) } @@ -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 diff --git a/poolakey/src/main/java/ir/cafebazaar/poolakey/ConnectionRequestResult.kt b/poolakey/src/main/java/ir/cafebazaar/poolakey/ConnectionRequestResult.kt new file mode 100644 index 0000000..c23f715 --- /dev/null +++ b/poolakey/src/main/java/ir/cafebazaar/poolakey/ConnectionRequestResult.kt @@ -0,0 +1,6 @@ +package ir.cafebazaar.poolakey + +internal data class ConnectionRequestResult( + val canConnect: Boolean, + val canUseFallback: Boolean = true +) diff --git a/poolakey/src/main/java/ir/cafebazaar/poolakey/PackageManager.kt b/poolakey/src/main/java/ir/cafebazaar/poolakey/PackageManager.kt index 79a2533..4bce3b5 100644 --- a/poolakey/src/main/java/ir/cafebazaar/poolakey/PackageManager.kt +++ b/poolakey/src/main/java/ir/cafebazaar/poolakey/PackageManager.kt @@ -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 @@ -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() } -} \ No newline at end of file +} + +internal fun isSdkNougatAndUp() = Build.VERSION.SDK_INT >= Build.VERSION_CODES.N + +internal fun isSdkPieAndUp() = Build.VERSION.SDK_INT >= Build.VERSION_CODES.P \ No newline at end of file diff --git a/poolakey/src/main/java/ir/cafebazaar/poolakey/billing/connection/BillingConnectionCommunicator.kt b/poolakey/src/main/java/ir/cafebazaar/poolakey/billing/connection/BillingConnectionCommunicator.kt index f338dab..9165365 100644 --- a/poolakey/src/main/java/ir/cafebazaar/poolakey/billing/connection/BillingConnectionCommunicator.kt +++ b/poolakey/src/main/java/ir/cafebazaar/poolakey/billing/connection/BillingConnectionCommunicator.kt @@ -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 @@ -18,7 +19,7 @@ internal interface BillingConnectionCommunicator { fun startConnection( context: Context, callback: ConnectionCallback - ): Boolean + ): ConnectionRequestResult fun consume( purchaseToken: String, diff --git a/poolakey/src/main/java/ir/cafebazaar/poolakey/billing/connection/ReceiverBillingConnection.kt b/poolakey/src/main/java/ir/cafebazaar/poolakey/billing/connection/ReceiverBillingConnection.kt index 8142af8..7ed486e 100644 --- a/poolakey/src/main/java/ir/cafebazaar/poolakey/billing/connection/ReceiverBillingConnection.kt +++ b/poolakey/src/main/java/ir/cafebazaar/poolakey/billing/connection/ReceiverBillingConnection.kt @@ -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 @@ -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 @@ -64,33 +66,36 @@ internal class ReceiverBillingConnection( private var purchaseWeakReference: WeakReference? = 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 { diff --git a/poolakey/src/main/java/ir/cafebazaar/poolakey/billing/connection/ServiceBillingConnection.kt b/poolakey/src/main/java/ir/cafebazaar/poolakey/billing/connection/ServiceBillingConnection.kt index 89a95fc..b6d531f 100644 --- a/poolakey/src/main/java/ir/cafebazaar/poolakey/billing/connection/ServiceBillingConnection.kt +++ b/poolakey/src/main/java/ir/cafebazaar/poolakey/billing/connection/ServiceBillingConnection.kt @@ -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 @@ -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 @@ -65,34 +66,33 @@ internal class ServiceBillingConnection( private var callbackReference: WeakReference? = null private var contextReference: WeakReference? = 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?) { @@ -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()