Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
olga-salina committed Oct 1, 2024
2 parents 71a8b2b + d849dd3 commit 14c1878
Show file tree
Hide file tree
Showing 10 changed files with 194 additions and 55 deletions.
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,15 @@
# Changelog
## [6.0.11] - Login SDK - 2024-10-01
### Fixed
- User registration via Xsolla Login Widget in WebView

## [1.4.2] - Payments SDK - 2024-10-01
### Changed
- `appendAnalytics(builder: Uri.Builder)` function. Added `browser_type` query parameter to URI that opens payment UI. Parameter is added for analytics purpose

### Fixed
- Custom Tabs related crash for specific devices

## [6.0.10] - Login SDK - 2024-09-11
### Changed
- `authenticateViaDeviceId` SDK method. Added `deviceId` optional parameter.
Expand Down
4 changes: 2 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@

buildscript {

ext.payments_sdk_version_name = '1.4.1'
ext.payments_sdk_version_name = '1.4.2'
ext.store_sdk_version_name = '2.5.10'
ext.inventory_sdk_version_name = '2.0.4'
ext.login_sdk_version_name = '6.0.10'
ext.login_sdk_version_name = '6.0.11'

ext.googleplay_sdk_version_name = "0.0.1"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ internal class ActivityAuthWebView : ActivityAuth() {
@SuppressLint("SetJavaScriptEnabled")
private fun configureWebView() {
webView.settings.javaScriptEnabled = true
webView.settings.domStorageEnabled = true
val socialNetwork = intent.getSerializableExtra(ARG_SOCIAL_NETWORK)
socialNetwork?.let {
when (socialNetwork as SocialNetwork) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import com.xsolla.android.payments.tracker.StatusTracker
import com.xsolla.android.payments.ui.ActivityOrientationLock
import com.xsolla.android.payments.ui.ActivityPayStation
import com.xsolla.android.payments.ui.ActivityType
import com.xsolla.android.payments.ui.utils.BrowserUtils
import com.xsolla.android.payments.ui.utils.TrustedWebActivityImageRef
import com.xsolla.android.payments.util.AnalyticsUtils
import kotlinx.parcelize.Parcelize
Expand Down Expand Up @@ -256,6 +257,10 @@ class XPayments private constructor(private val statusTracker: StatusTracker, in
ActivityPayStation.ARG_REDIRECT_SCHEME to redirectScheme,
ActivityPayStation.ARG_REDIRECT_HOST to redirectHost
)

Log.d(TAG, "generated PayStation url: $url")
Log.d(TAG, "received redirect host: $redirectHost and redirect scheme: $redirectScheme")

accessToken?.let { token ->
bundle.putString(ActivityPayStation.ARG_PAYMENT_TOKEN, token.token)
}
Expand Down Expand Up @@ -294,6 +299,7 @@ class XPayments private constructor(private val statusTracker: StatusTracker, in
}

private fun generateUrl(): String {

accessToken?.let {
val uriBuilder = Uri.Builder()
.scheme("https")
Expand All @@ -302,6 +308,7 @@ class XPayments private constructor(private val statusTracker: StatusTracker, in
.appendQueryParameter(getTokenQueryParameterName(), it.token)

appendAnalytics(uriBuilder)

return uriBuilder.build().toString()
}
throw IllegalArgumentException("access token isn't specified")
Expand All @@ -310,10 +317,18 @@ class XPayments private constructor(private val statusTracker: StatusTracker, in
private fun getServer() = if (isSandbox) SERVER_SANDBOX else SERVER_PROD

private fun appendAnalytics(builder: Uri.Builder){

val browserType = when (BrowserUtils.deduceActivityType(context, activityType)) {
ActivityType.WEB_VIEW -> "web_view"
ActivityType.CUSTOM_TABS -> "custom_tabs"
ActivityType.TRUSTED_WEB_ACTIVITY -> "trusted_web_activity"
}

builder.appendQueryParameter("engine", "android")
builder.appendQueryParameter("engine_v", Build.VERSION.RELEASE)
builder.appendQueryParameter("sdk", AnalyticsUtils.sdk)
builder.appendQueryParameter("sdk_v", AnalyticsUtils.sdkVersion)
builder.appendQueryParameter("browser_type", browserType)

if (AnalyticsUtils.gameEngine.isNotBlank())
builder.appendQueryParameter("game_engine", AnalyticsUtils.gameEngine)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import android.webkit.WebChromeClient
import android.webkit.WebView
import android.webkit.WebViewClient
import android.widget.Toast
import androidx.annotation.MainThread
import androidx.annotation.RequiresApi
import androidx.browser.customtabs.CustomTabsSession
import com.xsolla.android.payments.XPayments
Expand All @@ -30,7 +31,7 @@ class PayStationCache(val context: Context) {
XPayments.createIntentBuilder(context)
var locale = Locale.getDefault().language
if(locale.isEmpty()) locale = "en"
if(BrowserUtils.isCustomTabsBrowserAvailable(context)) {
if(BrowserUtils.getCustomTabsBrowserPackageName(context) != null) {
val payStation3WarmUpUrl = "https://secure.xsolla.com/paystation3/$locale/cache-warmup"
val payStation4WarmUpUrl = "https://secure.xsolla.com/paystation4/$locale/cache-warmup"
customTabHelper = CustomTabsHelper(
Expand Down Expand Up @@ -135,9 +136,10 @@ class PayStationCache(val context: Context) {
companion object {
private var instance: PayStationCache? = null

@MainThread
fun getInstance(context: Context): PayStationCache {
if (instance == null) {
instance = PayStationCache(context)
instance = PayStationCache(context.applicationContext).apply { init() }
}
return instance!!
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import androidx.startup.Initializer

class PayStationCacheInitializer: Initializer<PayStationCache> {
override fun create(context: Context): PayStationCache {
return PayStationCache.getInstance(context).apply { init() }
return PayStationCache.getInstance(context)
}

override fun dependencies(): List<Class<out Initializer<*>>> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,6 @@ internal class ActivityPayStation : AppCompatActivity() {
*/
private const val TRUSTED_WEB_ACTIVITY_FADE_OUT_TIME_IN_MILLIS = 250

fun checkAvailability(context: Context) =
BrowserUtils.isPlainBrowserAvailable(context)
|| BrowserUtils.isCustomTabsBrowserAvailable(context)
}

private lateinit var url: String
Expand All @@ -97,7 +94,7 @@ internal class ActivityPayStation : AppCompatActivity() {
private lateinit var redirectScheme: String
private lateinit var redirectHost: String
private var paymentToken: String? = null
private lateinit var type: ActivityType
private lateinit var activityType: ActivityType
private var orientationLock: ActivityOrientationLock? = null
private var trustedWebActivityBackgroundColor: Int? = null
private var trustedWebActivityImageRef: TrustedWebActivityImageRef? = null
Expand Down Expand Up @@ -128,17 +125,9 @@ internal class ActivityPayStation : AppCompatActivity() {
paymentToken = token
}

type = intent.getStringExtra(ARG_ACTIVITY_TYPE)
?.let { s -> ActivityType.valueOf(s.uppercase()) }
// If activity type wasn't specified directly, fallback
// to the "deprecated" method, i.e. via [ARG_USE_WEBVIEW]
// intent parameter.
?: if (BrowserUtils.isCustomTabsBrowserAvailable(this)) ActivityType.CUSTOM_TABS else ActivityType.WEB_VIEW
val receivedActivityType: ActivityType? = intent.getStringExtra(ARG_ACTIVITY_TYPE)?.let{ s -> ActivityType.valueOf(s.uppercase()) } ?: null


if(!checkAvailability(this)) {
type = ActivityType.WEB_VIEW
}
activityType = BrowserUtils.deduceActivityType(this, receivedActivityType)

orientationLock = intent.getStringExtra(ARG_ACTIVITY_ORIENTATION_LOCK)
?.let { s -> ActivityOrientationLock.valueOf(s.uppercase()) }
Expand Down Expand Up @@ -379,8 +368,8 @@ internal class ActivityPayStation : AppCompatActivity() {
dm.enqueue(request)
}

private fun isWebView() : Boolean = type == ActivityType.WEB_VIEW
private fun isTrustedWebActivity() : Boolean = type == ActivityType.TRUSTED_WEB_ACTIVITY
private fun isWebView() : Boolean = activityType == ActivityType.WEB_VIEW
private fun isTrustedWebActivity() : Boolean = activityType == ActivityType.TRUSTED_WEB_ACTIVITY

override fun onDestroy() {
super.onDestroy()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package com.xsolla.android.payments.ui.utils

import android.os.Handler
import android.os.Looper
import android.util.Log
import java.util.concurrent.Executor
import java.util.concurrent.Executors
import java.util.concurrent.Future
import java.util.concurrent.ThreadFactory
import java.util.concurrent.atomic.AtomicInteger

object AsyncUtils {
private val LOG_TAG = AsyncUtils.javaClass.simpleName

private val sThreadFactory = InternalThreadFactory()
private val sThreadPool = Executors.newCachedThreadPool(sThreadFactory)

private val sMainThreadExecutor = object : Executor {
private val mainHandler = Handler(Looper.getMainLooper())

override fun execute(r: Runnable) {
mainHandler.post(r)
}
}

fun run(runnable: Runnable) : Future<*>? {
try {
return sThreadPool.submit(runnable)
} catch (e: Exception) {
Log.d(LOG_TAG, "Failed to execute a task asynchronously.", e)
return null
}
}

fun runOnMainThread(runnable: Runnable) =
sMainThreadExecutor.execute(runnable)

class InternalThreadFactory : ThreadFactory {
private val threadFactory = Executors.defaultThreadFactory()
private val nextThreadId = AtomicInteger(1)

override fun newThread(r: Runnable?): Thread {
val thread = threadFactory.newThread(r)
val threadId = nextThreadId.getAndIncrement()
thread.name = "${THREAD_PREFIX}-${threadId}"
return thread;
}

companion object {
private const val THREAD_PREFIX = "XsollaPayments"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import androidx.core.content.ContextCompat
import com.google.androidbrowserhelper.trusted.ChromeLegacyUtils
import com.xsolla.android.payments.R
import com.xsolla.android.payments.caching.PayStationCache
import com.xsolla.android.payments.ui.ActivityType

object BrowserUtils {

Expand Down Expand Up @@ -52,8 +53,20 @@ object BrowserUtils {
}
}

/**
* Checks whether the system has a custom tabs compatible browser installed and
* a `CustomTabsSession` has been initialized.
*/
fun isCustomTabsBrowserAvailable(context: Context) =
getAvailableCustomTabsBrowsers(context).isNotEmpty() && CustomTabsHelper.IS_SUCCESSFULLY_INITIALIZED
getCustomTabsBrowserPackageName(context) != null &&
PayStationCache.getInstance(context).getCachedSession() != null

/**
* Returns the package name of a browser that supports custom tabs or
* `null` if there's none available.
*/
fun getCustomTabsBrowserPackageName(context: Context) : String? =
getAvailableCustomTabsBrowsers(context).firstOrNull { !TextUtils.isEmpty(it) }

fun isPlainBrowserAvailable(context: Context) =
getAvailablePlainBrowsers(context).isNotEmpty()
Expand Down Expand Up @@ -102,4 +115,13 @@ object BrowserUtils {
activity.startActivity(intent)
}

fun deduceActivityType(context: Context, preferredType: ActivityType?) : ActivityType {
var determinedType = preferredType ?: ActivityType.CUSTOM_TABS

if (determinedType == ActivityType.TRUSTED_WEB_ACTIVITY && isTrustedWebActivityAvailable(context)) return ActivityType.TRUSTED_WEB_ACTIVITY
if (determinedType == ActivityType.CUSTOM_TABS && isCustomTabsBrowserAvailable(context)) return ActivityType.CUSTOM_TABS

return ActivityType.WEB_VIEW
}

}
Loading

0 comments on commit 14c1878

Please sign in to comment.