Skip to content

Commit

Permalink
Release 4.4.2
Browse files Browse the repository at this point in the history
Release 4.4.2
  • Loading branch information
SpertsyanKM authored Jun 6, 2023
2 parents 9cd054a + 7944019 commit ea35674
Show file tree
Hide file tree
Showing 15 changed files with 384 additions and 35 deletions.
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import io.gitlab.arturbosch.detekt.DetektCreateBaselineTask
buildscript {
ext {
release = [
versionName: "4.4.1",
versionName: "4.4.2",
versionCode: 1
]
}
Expand Down
19 changes: 12 additions & 7 deletions config/detekt/baseline.xml
Original file line number Diff line number Diff line change
Expand Up @@ -166,8 +166,8 @@
<ID>MaxLineLength:QonversionBillingServiceTest.kt$QonversionBillingServiceTest.QueryPurchasesHistory$billingClientStateListener.onBillingSetupFinished(buildResult(BillingClient.BillingResponseCode.BILLING_UNAVAILABLE))</ID>
<ID>MaxLineLength:QonversionConfig.kt$QonversionConfig.Builder$*</ID>
<ID>MaxLineLength:QonversionError.kt$QonversionErrorCode$*</ID>
<ID>MaxLineLength:QonversionInternal.kt$QonversionInternal$val isHistoricalDataSynced: Boolean = sharedPreferencesCache?.getBool(Constants.IS_HISTORICAL_DATA_SYNCED) ?: false</ID>
<ID>MaxLineLength:QonversionRepositoryIntegrationTest.kt$QonversionRepositoryIntegrationTest$"""HTTP status code=400, data={"message":"Invalid access token received","code":10003,"status":400,"extra":[]}. """</ID>
<ID>MaxLineLength:QonversionRepositoryIntegrationTest.kt$QonversionRepositoryIntegrationTest$"lcbfeigohklhpdgmpildjabg.AO-J1OyV-EE2bKGqDcRCvqjZ2NI1uHDRuvonRn5RorP6LNsyK7yHK8FaFlXp6bjTEX3-4JvZKtbY_bpquKBfux09Mfkx05M9YGZsfsr5BJk74r719m77Oyo"</ID>
<ID>MaxLineLength:QonversionRepositoryIntegrationTest.kt$QonversionRepositoryIntegrationTest$"lgeigljfpmeoddkcebkcepjc.AO-J1Oy305qZj99jXTPEVBN8UZGoYAtjDLj4uTjRQvUFaG0vie-nr6VBlN0qnNDMU8eJR-sI7o3CwQyMOEHKl8eJsoQ86KSFzxKBR07PSpHLI_o7agXhNKY"</ID>
<ID>MaxLineLength:QonversionRepositoryIntegrationTest.kt$QonversionRepositoryIntegrationTest$detailsToken = "AEuhp4Kd9cZ3ZlkS2MylEXHBcZVLjwwllncPBm4a6lrVvj3uYGICnsE5w87i81qNsa38DPOW08BcZfLxJFxIWeISVwoBkT55tA2Bb6cKGsip724="</ID>
<ID>MaxLineLength:QonversionRepositoryIntegrationTest.kt$QonversionRepositoryIntegrationTest$purchaseToken = "lgeigljfpmeoddkcebkcepjc.AO-J1Oy305qZj99jXTPEVBN8UZGoYAtjDLj4uTjRQvUFaG0vie-nr6VBlN0qnNDMU8eJR-sI7o3CwQyMOEHKl8eJsoQ86KSFzxKBR07PSpHLI_o7agXhNKY"</ID>
Expand Down Expand Up @@ -204,13 +204,12 @@
<ID>MaximumLineLength:com.qonversion.android.sdk.internal.QProductCenterManagerTest.kt:157</ID>
<ID>MaximumLineLength:com.qonversion.android.sdk.internal.QProductCenterManagerTest.kt:159</ID>
<ID>MaximumLineLength:com.qonversion.android.sdk.internal.QUserPropertiesManagerTest.kt:172</ID>
<ID>MaximumLineLength:com.qonversion.android.sdk.internal.QonversionInternal.kt:114</ID>
<ID>MaximumLineLength:com.qonversion.android.sdk.internal.QonversionRepositoryIntegrationTest.kt:103</ID>
<ID>MaximumLineLength:com.qonversion.android.sdk.internal.QonversionRepositoryIntegrationTest.kt:127</ID>
<ID>MaximumLineLength:com.qonversion.android.sdk.internal.QonversionRepositoryIntegrationTest.kt:115</ID>
<ID>MaximumLineLength:com.qonversion.android.sdk.internal.QonversionRepositoryIntegrationTest.kt:325</ID>
<ID>MaximumLineLength:com.qonversion.android.sdk.internal.QonversionRepositoryIntegrationTest.kt:376</ID>
<ID>MaximumLineLength:com.qonversion.android.sdk.internal.QonversionRepositoryIntegrationTest.kt:646</ID>
<ID>MaximumLineLength:com.qonversion.android.sdk.internal.QonversionRepositoryIntegrationTest.kt:867</ID>
<ID>MaximumLineLength:com.qonversion.android.sdk.internal.QonversionRepositoryIntegrationTest.kt:388</ID>
<ID>MaximumLineLength:com.qonversion.android.sdk.internal.QonversionRepositoryIntegrationTest.kt:658</ID>
<ID>MaximumLineLength:com.qonversion.android.sdk.internal.QonversionRepositoryIntegrationTest.kt:879</ID>
<ID>MaximumLineLength:com.qonversion.android.sdk.internal.QonversionRepositoryIntegrationTest.kt:91</ID>
<ID>MaximumLineLength:com.qonversion.android.sdk.internal.api.ApiErrorMapper.kt:117</ID>
<ID>MaximumLineLength:com.qonversion.android.sdk.internal.api.ApiErrorMapper.kt:118</ID>
<ID>MaximumLineLength:com.qonversion.android.sdk.internal.billing.QonversionBillingService.kt:109</ID>
Expand Down Expand Up @@ -320,6 +319,8 @@
<ID>NoWildcardImports:com.qonversion.android.sdk.internal.storage.util.kt:29</ID>
<ID>NoWildcardImports:com.qonversion.android.sdk.internal.storage.util.kt:3</ID>
<ID>ReturnCount:AutomationsEventMapper.kt$AutomationsEventMapper$fun getEventFromRemoteMessage(messageData: Map&lt;String, String&gt;): AutomationsEvent?</ID>
<ID>ReturnCount:ExceptionHandler.kt$ExceptionHandler$private fun isQonversionException(exception: Throwable): Boolean</ID>
<ID>ReturnCount:QExceptionManager.kt$QExceptionManager$private fun getContentOfCrashReport(filename: String): CrashRequest.ExceptionInfo?</ID>
<ID>ReturnCount:QProductCenterManager.kt$QProductCenterManager$@Synchronized private fun executeProductsBlocks(loadStoreProductsError: QonversionError? = null)</ID>
<ID>ReturnCount:QProductCenterManager.kt$QProductCenterManager$private fun loadStoreProductsIfPossible( onLoadCompleted: ((products: List&lt;SkuDetails&gt;) -&gt; Unit)? = null, onLoadFailed: ((error: QonversionError) -&gt; Unit)? = null )</ID>
<ID>ReturnCount:QProductCenterManager.kt$QProductCenterManager$private fun processPurchase( context: Activity, productId: String, oldProductId: String?, @BillingFlowParams.ProrationMode prorationMode: Int?, offeringId: String?, callback: QonversionEntitlementsCallback )</ID>
Expand Down Expand Up @@ -351,6 +352,7 @@
<ID>SwallowedException:Automations.kt$Automations.Companion$catch (e: UninitializedPropertyAccessException) { throw UninitializedPropertyAccessException("Qonversion has not been initialized. " + "Automations should be used after Qonversion is initialized.") }</ID>
<ID>SwallowedException:AutomationsEventMapper.kt$AutomationsEventMapper$catch (e: JSONException) { logger.release("getEventFromRemoteMessage() -&gt; Failed to retrieve event that triggered push notification") }</ID>
<ID>SwallowedException:EnvironmentProvider.kt$EnvironmentProvider$catch (throwable: Throwable) { UNKNOWN }</ID>
<ID>SwallowedException:ExceptionHandler.kt$ExceptionHandler$catch (e: Exception) { "" }</ID>
<ID>SwallowedException:FacebookAttribution.kt$FacebookAttribution$catch (e: Exception) { null }</ID>
<ID>SwallowedException:PurchasesCache.kt$PurchasesCache$catch (e: IOException) { setOf() }</ID>
<ID>SwallowedException:QAutomationsManager.kt$QAutomationsManager$catch (e: JSONException) { null }</ID>
Expand All @@ -361,8 +363,11 @@
<ID>ThrowingExceptionsWithoutMessageOrCause:AdvertisingProvider.kt$AdvertisingProvider.AdvertisingConnection$IllegalStateException()</ID>
<ID>TooGenericExceptionCaught:AdvertisingProvider.kt$AdvertisingProvider$e: Exception</ID>
<ID>TooGenericExceptionCaught:EnvironmentProvider.kt$EnvironmentProvider$throwable: Throwable</ID>
<ID>TooGenericExceptionCaught:ExceptionHandler.kt$ExceptionHandler$cause: Exception</ID>
<ID>TooGenericExceptionCaught:ExceptionHandler.kt$ExceptionHandler$e: Exception</ID>
<ID>TooGenericExceptionCaught:FacebookAttribution.kt$FacebookAttribution$e: Exception</ID>
<ID>TooGenericExceptionCaught:QAutomationsManager.kt$QAutomationsManager$e: Exception</ID>
<ID>TooGenericExceptionCaught:QExceptionManager.kt$QExceptionManager$cause: Exception</ID>
<ID>TooGenericExceptionCaught:ScreenFragment.kt$ScreenFragment$e: Exception</ID>
<ID>TooManyFunctions:Api.kt$Api</ID>
<ID>TooManyFunctions:AppComponent.kt$AppComponent</ID>
Expand Down
2 changes: 1 addition & 1 deletion fastlane/report.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@



<testcase classname="fastlane.lanes" name="0: default_platform" time="0.113381">
<testcase classname="fastlane.lanes" name="0: default_platform" time="0.071441">

</testcase>

Expand Down
1 change: 0 additions & 1 deletion sdk/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,6 @@ dependencies {

// UI
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'androidx.fragment:fragment-ktx:1.2.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'

// Billing
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,18 +87,6 @@ internal class QonversionRepositoryIntegrationTest {
"test_inapp" to listOf("noAds")
)

private val expectedPermissions = mapOf(
"premium" to QPermission(
"premium",
"test_monthly",
QProductRenewState.Canceled,
Date(1679933171000),
Date(1679935273000),
QEntitlementSource.PlayStore,
0
)
)

private val purchase = Purchase(
detailsToken = "AEuhp4Kd9cZ3ZlkS2MylEXHBcZVLjwwllncPBm4a6lrVvj3uYGICnsE5w87i81qNsa38DPOW08BcZfLxJFxIWeISVwoBkT55tA2Bb6cKGsip724=",
title = "DONT CHANGE! Sub for integration tests. (Qonversion Sample)",
Expand Down Expand Up @@ -253,6 +241,18 @@ internal class QonversionRepositoryIntegrationTest {
// given
val signal = CountDownLatch(1)

val expectedPermissions = mapOf(
"premium" to QPermission(
"premium",
"test_monthly",
QProductRenewState.Canceled,
Date(1679933171000),
Date(1679935273000),
QEntitlementSource.PlayStore,
0
)
)

val uid = "QON_test_uid1679992132407"
val callback = object : QonversionLaunchCallback {
override fun onSuccess(launchResult: QLaunchResult) {
Expand Down Expand Up @@ -321,11 +321,23 @@ internal class QonversionRepositoryIntegrationTest {

val history = listOf(
History(
"google_monthly",
"lgeigljfpmeoddkcebkcepjc.AO-J1Oy305qZj99jXTPEVBN8UZGoYAtjDLj4uTjRQvUFaG0vie-nr6VBlN0qnNDMU8eJR-sI7o3CwQyMOEHKl8eJsoQ86KSFzxKBR07PSpHLI_o7agXhNKY",
1679933171,
"SGD",
"6.99"
"google_inapp",
"lcbfeigohklhpdgmpildjabg.AO-J1OyV-EE2bKGqDcRCvqjZ2NI1uHDRuvonRn5RorP6LNsyK7yHK8FaFlXp6bjTEX3-4JvZKtbY_bpquKBfux09Mfkx05M9YGZsfsr5BJk74r719m77Oyo",
1685953401,
"GBP",
"48.9"
)
)

val expectedPermissions = mapOf(
"noAds" to QPermission(
"noAds",
"test_inapp",
QProductRenewState.NonRenewable,
Date(1685953401000),
null,
QEntitlementSource.PlayStore,
1
)
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,6 @@ internal object Constants {
const val INTERNAL_SERVER_ERROR_MIN = 500
const val INTERNAL_SERVER_ERROR_MAX = 599
const val PRICE_MICROS_DIVIDER: Double = 1000000.0
const val CRASH_LOGS_URL = "https://sdk-logs.qonversion.io/sdk.log"
const val CRASH_LOG_FILE_SUFFIX = ".qonversion.stacktrace"
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import com.qonversion.android.sdk.internal.dto.QLaunchResult
import com.qonversion.android.sdk.dto.QUserProperty
import com.qonversion.android.sdk.dto.eligibility.QEligibility
import com.qonversion.android.sdk.dto.offerings.QOfferings
import com.qonversion.android.sdk.internal.logger.ExceptionManager
import com.qonversion.android.sdk.internal.provider.AppStateProvider
import com.qonversion.android.sdk.internal.storage.SharedPreferencesCache
import com.qonversion.android.sdk.listeners.QEntitlementsUpdateListener
Expand All @@ -40,6 +41,7 @@ internal class QonversionInternal(
private var logger = ConsoleLogger()
private val handler = Handler(Looper.getMainLooper())
private var sharedPreferencesCache: SharedPreferencesCache? = null
private var exceptionManager: ExceptionManager? = null

override var appState = AppState.Background

Expand All @@ -49,6 +51,10 @@ internal class QonversionInternal(

QDependencyInjector.buildAppComponent(application, internalConfig, this)

exceptionManager = QDependencyInjector.appComponent.exceptionManager().also {
it.initialize(application)
}

val repository = QDependencyInjector.appComponent.repository()
val purchasesCache = QDependencyInjector.appComponent.purchasesCache()
val handledPurchasesCache = QDependencyInjector.appComponent.handledPurchasesCache()
Expand Down Expand Up @@ -111,7 +117,8 @@ internal class QonversionInternal(
}

override fun syncHistoricalData() {
val isHistoricalDataSynced: Boolean = sharedPreferencesCache?.getBool(Constants.IS_HISTORICAL_DATA_SYNCED) ?: false
val isHistoricalDataSynced: Boolean =
sharedPreferencesCache?.getBool(Constants.IS_HISTORICAL_DATA_SYNCED) ?: false
if (isHistoricalDataSynced) {
return
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import com.qonversion.android.sdk.internal.dto.request.PurchaseRequest
import com.qonversion.android.sdk.internal.dto.request.ViewsRequest
import com.qonversion.android.sdk.internal.dto.request.EventRequest
import com.qonversion.android.sdk.internal.dto.request.AttributionRequest
import com.qonversion.android.sdk.internal.dto.request.CrashRequest
import com.qonversion.android.sdk.internal.dto.request.RestoreRequest
import com.qonversion.android.sdk.internal.dto.request.InitRequest
import com.qonversion.android.sdk.internal.dto.request.EligibilityRequest
Expand Down Expand Up @@ -276,6 +277,29 @@ internal class QonversionRepository internal constructor(
eventRequest(EXPERIMENT_STARTED_EVENT_NAME, payload)
}

fun crashReport(
crashData: CrashRequest,
onSuccess: () -> Unit,
onError: (error: QonversionError) -> Unit
) {
api.crashLogs(crashData).enqueue {
onResponse = {
logger.release("crashReportRequest - ${it.getLogMessage()}")
if (it.isSuccessful) {
onSuccess()
} else {
onError(errorMapper.getErrorFromResponse(it))
}
}
onFailure = {
logger.release("crashReportRequest - failure - ${it.toQonversionError()}")
onError(it.toQonversionError())
}
}
}

// Private functions

private fun eventRequest(eventName: String, payload: Map<String, Any>) {
val eventRequest = EventRequest(
userId = uid,
Expand All @@ -293,8 +317,6 @@ internal class QonversionRepository internal constructor(
}
}

// Private functions

private fun createAttributionRequest(
conversionInfo: Map<String, Any>,
from: String
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.qonversion.android.sdk.internal.api

import com.qonversion.android.sdk.internal.Constants.CRASH_LOGS_URL
import com.qonversion.android.sdk.internal.dto.automations.Screen
import com.qonversion.android.sdk.internal.dto.eligibility.EligibilityResult
import com.qonversion.android.sdk.internal.dto.identity.IdentityResult
Expand All @@ -9,6 +10,7 @@ import com.qonversion.android.sdk.internal.dto.Data
import com.qonversion.android.sdk.internal.dto.QLaunchResult
import com.qonversion.android.sdk.internal.dto.Response
import com.qonversion.android.sdk.internal.dto.request.AttributionRequest
import com.qonversion.android.sdk.internal.dto.request.CrashRequest
import com.qonversion.android.sdk.internal.dto.request.EligibilityRequest
import com.qonversion.android.sdk.internal.dto.request.EventRequest
import com.qonversion.android.sdk.internal.dto.request.IdentityRequest
Expand All @@ -22,8 +24,10 @@ import retrofit2.Call
import retrofit2.http.POST
import retrofit2.http.GET
import retrofit2.http.Body
import retrofit2.http.Headers
import retrofit2.http.Path
import retrofit2.http.QueryMap
import retrofit2.http.Url

internal interface Api {

Expand Down Expand Up @@ -65,4 +69,8 @@ internal interface Api {

@POST("v2/events")
fun events(@Body request: EventRequest): Call<Void>

@Headers("Content-Type: application/json")
@POST
fun crashLogs(@Body request: CrashRequest, @Url url: String = CRASH_LOGS_URL): Call<Void>
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,19 +31,25 @@ internal class ApiHeadersProvider @Inject constructor(

private fun getHeadersMap() = mapOf(
CONTENT_TYPE to "application/json",
AUTHORIZATION to getBearer(projectKey),
AUTHORIZATION to getBearer(getProjectKey()),
USER_LOCALE to getLocale(),
SOURCE to getSource(),
SOURCE_VERSION to getSourceVersion(),
PLATFORM to ANDROID_PLATFORM,
PLATFORM_VERSION to Build.VERSION.RELEASE,
PLATFORM to getPlatform(),
PLATFORM_VERSION to getPlatformVersion(),
UID to config.uid
)

private fun getSource() =
fun getProjectKey() = projectKey

fun getPlatform() = ANDROID_PLATFORM

fun getPlatformVersion(): String = Build.VERSION.RELEASE

fun getSource() =
sharedPreferencesCache.getString(PREFS_SOURCE_KEY, null) ?: ANDROID_PLATFORM

private fun getSourceVersion() =
fun getSourceVersion() =
sharedPreferencesCache.getString(PREFS_SOURCE_VERSION_KEY, null) ?: config.primaryConfig.sdkVersion

companion object {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import com.qonversion.android.sdk.internal.di.module.RepositoryModule
import com.qonversion.android.sdk.internal.di.module.NetworkModule
import com.qonversion.android.sdk.internal.di.module.ManagersModule
import com.qonversion.android.sdk.internal.di.module.ServicesModule
import com.qonversion.android.sdk.internal.logger.QExceptionManager
import com.qonversion.android.sdk.internal.provider.AppStateProvider
import com.qonversion.android.sdk.internal.services.QUserInfoService
import com.qonversion.android.sdk.internal.storage.LaunchResultCacheWrapper
Expand Down Expand Up @@ -40,4 +41,5 @@ internal interface AppComponent {
fun internalConfig(): InternalConfig
fun appStateProvider(): AppStateProvider
fun sharedPreferencesCache(): SharedPreferencesCache
fun exceptionManager(): QExceptionManager
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package com.qonversion.android.sdk.internal.dto.request

import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass

@JsonClass(generateAdapter = true)
internal data class CrashRequest(
@Json(name = "exception") val log: ExceptionInfo,
@Json(name = "device") val deviceInfo: DeviceInfo
) {
@JsonClass(generateAdapter = true)
data class ExceptionInfo(
@Json(name = "title") val title: String,
@Json(name = "place") val place: String,
@Json(name = "traces") val traces: List<ExceptionTrace>
)

@JsonClass(generateAdapter = true)
data class ExceptionTrace(
@Json(name = "rawStackTrace") val rawStackTrace: String,
@Json(name = "class") val className: String,
@Json(name = "message") val message: String,
@Json(name = "elements") val elements: List<ExceptionTraceElement>
)

@JsonClass(generateAdapter = true)
data class ExceptionTraceElement(
@Json(name = "class") val className: String,
@Json(name = "file") val fileName: String,
@Json(name = "method") val methodName: String,
@Json(name = "line") val line: Int
)

@JsonClass(generateAdapter = true)
data class DeviceInfo(
@Json(name = "platform") val platform: String,
@Json(name = "platform_version") val platformVersion: String,
@Json(name = "source") val source: String,
@Json(name = "source_version") val sourceVersion: String,
@Json(name = "project_key") val projectKey: String,
@Json(name = "uid") val uid: String
)
}
Loading

0 comments on commit ea35674

Please sign in to comment.