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 May 6, 2024
2 parents 55c6aaa + ebec1a4 commit 0333288
Show file tree
Hide file tree
Showing 14 changed files with 326 additions and 23 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
# Changelog
## [2.5.6] - Store SDK - 2024-05-06
### Changed
- `getVirtualItems` SDK method. Added the `requestGeoLocale` parameter. If `true`, the response returns the locale in the `geoLocale` parameter.

## [1.3.4] - Payments SDK - 2024-05-06
### Added
- Pay Station preloader. Allows faster content display in WebView and Custom Tabs.

## [2.2.11] - Demo Apps - 2024-04-11
### Fixed
- Token refresh on application startup
Expand Down
4 changes: 2 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

buildscript {

ext.payments_sdk_version_name = '1.3.3'
ext.store_sdk_version_name = '2.5.5'
ext.payments_sdk_version_name = '1.3.4'
ext.store_sdk_version_name = '2.5.6'
ext.inventory_sdk_version_name = '2.0.4'
ext.login_sdk_version_name = '6.0.7'

Expand Down
2 changes: 2 additions & 0 deletions xsolla-payments-sdk/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ dependencies {
implementation "androidx.core:core-ktx:$androidx_core_ktx"

implementation "androidx.browser:browser:$androidx_browser"

implementation "androidx.startup:startup-runtime:1.1.1"
}

dokkaHtmlPartial {
Expand Down
9 changes: 9 additions & 0 deletions xsolla-payments-sdk/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.xsolla.android.payments">

<queries>
Expand Down Expand Up @@ -30,6 +31,14 @@
android:scheme="app" />
</intent-filter>
</activity>
<provider
android:name="androidx.startup.InitializationProvider"
android:authorities="${applicationId}.androidx-startup"
android:exported="false"
tools:node="merge">
<meta-data android:name="com.xsolla.android.payments.caching.PayStationCacheInitializer"
android:value="androidx.startup" />
</provider>
</application>

</manifest>
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import android.content.Intent
import android.net.Uri
import android.os.Build
import android.os.Parcelable
import android.util.Log
import androidx.core.os.bundleOf
import com.xsolla.android.payments.caching.PayStationCache
import com.xsolla.android.payments.data.AccessToken
import com.xsolla.android.payments.ui.ActivityPayStation
import com.xsolla.android.payments.util.AnalyticsUtils
Expand Down Expand Up @@ -81,8 +81,7 @@ class XPayments {
*/
fun build(): Intent {
val url = generateUrl()
val intent = Intent()
intent.setClass(context, ActivityPayStation::class.java)
var intent = PayStationCache.getInstance(context).getCachedIntent()
intent.putExtras(
bundleOf(
ActivityPayStation.ARG_URL to url,
Expand Down Expand Up @@ -173,4 +172,5 @@ class XPayments {
V3,
V4
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
package com.xsolla.android.payments.caching

import android.content.Context
import android.content.Intent
import android.os.Build
import android.util.Log
import android.view.ViewGroup
import android.webkit.RenderProcessGoneDetail
import android.webkit.WebChromeClient
import android.webkit.WebView
import android.webkit.WebViewClient
import android.widget.Toast
import androidx.annotation.RequiresApi
import androidx.browser.customtabs.CustomTabsSession
import com.xsolla.android.payments.XPayments
import com.xsolla.android.payments.ui.ActivityPayStation
import com.xsolla.android.payments.ui.utils.BrowserUtils
import com.xsolla.android.payments.ui.utils.CustomTabsHelper
import java.util.Locale


class PayStationCache(val context: Context) {

private lateinit var preloadingWebView:WebView
private var cachedIntent: Intent? = null
private lateinit var customTabHelper: CustomTabsHelper

fun init() {
XPayments.createIntentBuilder(context)
var locale = Locale.getDefault().language
if(locale.isEmpty()) locale = "en"
if(BrowserUtils.isCustomTabsBrowserAvailable(context)) {
val payStation3WarmUpUrl = "https://secure.xsolla.com/paystation3/$locale/cache-warmup"
val payStation4WarmUpUrl = "https://secure.xsolla.com/paystation4/$locale/cache-warmup"
customTabHelper = CustomTabsHelper(context, payStation3WarmUpUrl, payStation4WarmUpUrl)
customTabHelper.bindCustomTabsService()
} else {
preloadUrl("https://secure.xsolla.com/paystation4/$locale/cache-warmup")
}
}

fun getCachedIntent(): Intent {
if(cachedIntent == null) {
val newIntent = Intent()
newIntent.setClass(context, ActivityPayStation::class.java)
cachedIntent = newIntent
}
return cachedIntent!!
}

fun getCachedSession(): CustomTabsSession? {
return customTabHelper.getSession()
}

private fun preloadUrl(url: String) {
preloadingWebView = prepareWebView(context)
loadUrl(url, preloadingWebView)
}

private fun prepareWebView(context: Context): WebView {
val webView = WebView(context)
setupWebViewWithDefaults(webView)
return webView
}

private fun setupWebViewWithDefaults(webView: WebView) {
setWebViewSettings(webView)
setBrowserClients(webView)
}

private fun setWebViewSettings(webView: WebView?) {
requireNotNull(webView) { "WebView should not be null!" }
webView.settings.javaScriptEnabled = true
webView.settings.domStorageEnabled = true
webView.settings.allowFileAccess = true
webView.settings.loadsImagesAutomatically = true
}

private fun setBrowserClients(webView: WebView?) {
requireNotNull(webView) { "WebView should not be null!" }
try {
webView.webViewClient = object : WebViewClient() {
override fun shouldOverrideUrlLoading(webview: WebView, url: String): Boolean {
Log.d(TAG, "shouldOverrideUrlLoading intercept url: $url")
webView.loadUrl(url)
return true
}

override fun onReceivedError(view: WebView, errorCode: Int, description: String, failingUrl: String) {
val url = view.originalUrl
Toast.makeText(view.context, "Load failed with error: $description", Toast.LENGTH_LONG).show()
}

@RequiresApi(Build.VERSION_CODES.O)
override fun onRenderProcessGone(view: WebView, detail: RenderProcessGoneDetail): Boolean {
if (!detail.didCrash()) {
Log.d(TAG, "System killed the WebView rendering process to reclaim memory. Recreating...")
if (view != null) {
val webViewContainer = view.parent as ViewGroup
if (webViewContainer != null && webViewContainer.childCount > 0) {
webViewContainer.removeView(view)
}
view.destroy()
}
return true
}
return false
}
}
webView.webChromeClient = object : WebChromeClient() {
override fun onProgressChanged(view: WebView, newProgress: Int) {
super.onProgressChanged(view, newProgress)
Log.d(TAG, "onProgressChanged: $newProgress")
if (view != null && newProgress == 100) {
val url = view.originalUrl
Log.d(TAG, "Preloading is done!")
}
}
}
} catch (e: Exception) {
Log.d(TAG, e.message, e)
}
}

private fun loadUrl(url: String, webView: WebView) {
webView.loadUrl(url)
}

companion object {
private var instance: PayStationCache? = null

fun getInstance(context: Context): PayStationCache {
if(instance == null) {
instance = PayStationCache(context)
}
return instance!!
}

private const val TAG = "PayStationCache"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.xsolla.android.payments.caching

import android.content.Context
import androidx.startup.Initializer

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

override fun dependencies(): List<Class<out Initializer<*>>> {
return emptyList()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import android.webkit.WebChromeClient
import android.webkit.WebView
import android.webkit.WebView.WebViewTransport
import android.webkit.WebViewClient
import android.widget.FrameLayout
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import com.xsolla.android.payments.R
Expand All @@ -41,6 +42,7 @@ internal class ActivityPayStation : AppCompatActivity() {
private lateinit var url: String
private lateinit var webView: WebView
private lateinit var childWebView: WebView
private lateinit var loader: FrameLayout

private lateinit var redirectScheme: String
private lateinit var redirectHost: String
Expand Down Expand Up @@ -82,6 +84,7 @@ internal class ActivityPayStation : AppCompatActivity() {
setContentView(R.layout.xsolla_payments_activity_paystation)
webView = findViewById(R.id.webview)
childWebView = findViewById(R.id.childWebView)
loader = findViewById(R.id.loader)
configureWebView()
webView.loadUrl(url)
} else {
Expand Down Expand Up @@ -193,7 +196,10 @@ internal class ActivityPayStation : AppCompatActivity() {
}
super.doUpdateVisitedHistory(view, url, isReload)
}

override fun onPageFinished(view: WebView?, url: String?) {
loader.visibility = View.GONE
super.onPageFinished(view, url)
}
}
webView.setDownloadListener { url, userAgent, contentDisposition, mimeType, _ ->

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import androidx.browser.customtabs.CustomTabsIntent
import androidx.browser.customtabs.CustomTabsService.ACTION_CUSTOM_TABS_CONNECTION
import androidx.core.content.ContextCompat
import com.xsolla.android.payments.R
import com.xsolla.android.payments.caching.PayStationCache

object BrowserUtils {

Expand All @@ -26,7 +27,7 @@ object BrowserUtils {
}
}

private fun getAvailableCustomTabsBrowsers(context: Context): List<String> {
fun getAvailableCustomTabsBrowsers(context: Context): List<String> {
val browserIntent = Intent()
.setAction(Intent.ACTION_VIEW)
.addCategory(Intent.CATEGORY_BROWSABLE)
Expand Down Expand Up @@ -66,14 +67,13 @@ object BrowserUtils {
)
.build()

val intent = CustomTabsIntent.Builder()
val customTabsIntent = CustomTabsIntent.Builder(PayStationCache.getInstance(context).getCachedSession())
.setDefaultColorSchemeParams(colorSchemeParams)
.setShowTitle(true)
.setUrlBarHidingEnabled(true)
.build()
intent.intent.`package` = getAvailableCustomTabsBrowsers(context).first()

intent.launchUrl(context, Uri.parse(url))
customTabsIntent.intent.setPackage(getAvailableCustomTabsBrowsers(context).first())
customTabsIntent.launchUrl(context, Uri.parse(url))
}

fun launchPlainBrowser(activity: Activity, url: String) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package com.xsolla.android.payments.ui.utils

import android.content.ComponentName
import android.content.Context
import android.net.Uri
import androidx.browser.customtabs.CustomTabsClient
import androidx.browser.customtabs.CustomTabsServiceConnection
import androidx.browser.customtabs.CustomTabsSession

class CustomTabsHelper(private val context: Context, private val payStation3WarmUpUrl: String, private val payStation4WarmUpUrl: String) {

private var customTabsSession: CustomTabsSession? = null
private var mClient: CustomTabsClient? = null

private var connection: CustomTabsServiceConnection? = object : CustomTabsServiceConnection() {
override fun onCustomTabsServiceConnected(name: ComponentName, client: CustomTabsClient) {
if (client != null) {
mClient = client
client.warmup(0)
customTabsSession = client.newSession(null)
customTabsSession!!.mayLaunchUrl(Uri.parse(payStation3WarmUpUrl), null, null)
customTabsSession!!.mayLaunchUrl(Uri.parse(payStation4WarmUpUrl), null, null)

}
}

override fun onServiceDisconnected(name: ComponentName) {
mClient = null
customTabsSession = null
}
}

fun bindCustomTabsService() {

if (mClient != null) return
val availableBrowsers = BrowserUtils.getAvailableCustomTabsBrowsers(context)

if(availableBrowsers.isEmpty()) return

val packageName = BrowserUtils.getAvailableCustomTabsBrowsers(context).first()

CustomTabsClient.bindCustomTabsService(context, packageName, connection!!)
}

fun unbindCustomTabsService() {
connection ?: return
context.unbindService(connection!!)
mClient = null
customTabsSession = null
connection = null
}

fun getSession(): CustomTabsSession? {
if (mClient == null) {
customTabsSession = null
} else if (customTabsSession == null) {
customTabsSession = mClient!!.newSession(null)
}
return customTabsSession
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,22 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone" />

<FrameLayout
android:id="@+id/loader"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="true"
android:focusable="true">
<View
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#1C1C1E"/>
<ProgressBar
android:indeterminateTint="#B2B2B4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"/>
</FrameLayout>

</FrameLayout>
Loading

0 comments on commit 0333288

Please sign in to comment.