Skip to content

Commit

Permalink
Merge branch 'development' into 'master'
Browse files Browse the repository at this point in the history
Development

See merge request apphud/android!7
  • Loading branch information
Nikolay Goldin committed Nov 23, 2020
2 parents b39d213 + 9f5071d commit 95d7261
Show file tree
Hide file tree
Showing 26 changed files with 249 additions and 78 deletions.
4 changes: 2 additions & 2 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ android {
applicationId "com.apphud.mbdg.myapplication"
minSdkVersion 16
targetSdkVersion 29
versionCode 14
versionName "1.0.12"
versionCode 17
versionName "1.0.15"

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
Expand Down
62 changes: 46 additions & 16 deletions sdk/src/main/java/com/apphud/sdk/ApphudInternal.kt
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,7 @@ import com.apphud.sdk.body.PurchaseBody
import com.apphud.sdk.body.PurchaseItemBody
import com.apphud.sdk.body.RegistrationBody
import com.apphud.sdk.client.ApphudClient
import com.apphud.sdk.domain.Customer
import com.apphud.sdk.domain.PurchaseDetails
import com.apphud.sdk.domain.PurchaseRecordDetails
import com.apphud.sdk.domain.*
import com.apphud.sdk.internal.BillingWrapper
import com.apphud.sdk.parser.GsonParser
import com.apphud.sdk.parser.Parser
Expand All @@ -31,7 +29,6 @@ internal object ApphudInternal {
.setPrettyPrinting()
.create()
private val parser: Parser = GsonParser(builder)
private var appsflyerBody: AttributionBody? = null

/**
* @handler use for work with UI-thread. Save to storage, call callbacks
Expand All @@ -41,6 +38,7 @@ internal object ApphudInternal {
private val billing by lazy { BillingWrapper(context) }
private val storage by lazy { SharedPreferencesStorage(context, parser) }
private var generatedUUID = UUID.randomUUID().toString()
private var prevPurchases = mutableSetOf<PurchaseRecordDetails>()

private var advertisingId: String? = null
get() = storage.advertisingId
Expand Down Expand Up @@ -105,6 +103,11 @@ internal object ApphudInternal {
if (isFetchProducts) {
// try to continue anyway, because maybe already has cached data, try to fetch products
fetchProducts()

// try to resend purchases, if prev requests was fail
if (storage.isNeedSync) {
syncPurchases()
}
}
}

Expand All @@ -121,13 +124,14 @@ internal object ApphudInternal {
}
billing.purchasesCallback = { purchases ->
ApphudLog.log("purchases: $purchases")

client.purchased(mkPurchasesBody(purchases)) { customer ->
handler.post {
apphudListener?.apphudSubscriptionsUpdated(customer.subscriptions)
apphudListener?.apphudNonRenewingPurchasesUpdated(customer.purchases)
}
ApphudLog.log("Response from server after success purchases: $purchases")
}

callback.invoke(purchases.map { it.purchase })

purchases.forEach {
Expand All @@ -148,13 +152,22 @@ internal object ApphudInternal {
}

internal fun syncPurchases() {
storage.isNeedSync = true
billing.restoreCallback = { records ->
client.purchased(mkPurchaseBody(records)) { customer ->
handler.post {
apphudListener?.apphudSubscriptionsUpdated(customer.subscriptions)
apphudListener?.apphudNonRenewingPurchasesUpdated(customer.purchases)

ApphudLog.log("$records")

when {
prevPurchases.containsAll(records) -> ApphudLog.log("Don't send equal purchases from prev state")
else -> client.purchased(mkPurchaseBody(records)) { customer ->
handler.post {
prevPurchases.addAll(records)
storage.isNeedSync = false
apphudListener?.apphudSubscriptionsUpdated(customer.subscriptions)
apphudListener?.apphudNonRenewingPurchasesUpdated(customer.purchases)
}
ApphudLog.log("success send history purchases $records")
}
ApphudLog.log("success send history purchases $records")
}
}
billing.historyCallback = { purchases ->
Expand Down Expand Up @@ -197,12 +210,28 @@ internal object ApphudInternal {
}

if (provider == ApphudAttributionProvider.appsFlyer) {
val temporary = appsflyerBody
appsflyerBody = when {
temporary == null -> body
temporary.appsflyer_id != body?.appsflyer_id -> body
temporary.appsflyer_data != body?.appsflyer_data -> body
else -> return
val temporary = storage.appsflyer
storage.appsflyer = when {
temporary == null -> AppsflyerInfo(
id = body?.appsflyer_id,
data = body?.appsflyer_data
)
temporary.id != body?.appsflyer_id -> AppsflyerInfo(
id = body?.appsflyer_id,
data = body?.appsflyer_data
)
temporary.data != body?.appsflyer_data -> AppsflyerInfo(
id = body?.appsflyer_id,
data = body?.appsflyer_data
)
else -> return
}
} else if (provider == ApphudAttributionProvider.facebook) {
val temporary = storage.facebook
storage.facebook = when {
temporary == null -> FacebookInfo(body?.facebook_data)
temporary.data != body?.facebook_data -> FacebookInfo(body?.facebook_data)
else -> return
}
}

Expand All @@ -224,6 +253,7 @@ internal object ApphudInternal {
storage.deviceId = null
userId = null
generatedUUID = UUID.randomUUID().toString()
prevPurchases.clear()
}

private fun fetchProducts() {
Expand Down
4 changes: 3 additions & 1 deletion sdk/src/main/java/com/apphud/sdk/aliases.kt
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,6 @@ typealias Callback<T> = (T) -> Unit
typealias CustomerCallback = Callback<Customer>
typealias ProductsCallback = Callback<List<Product>>
typealias AttributionCallback = Callback<Attribution>
typealias PurchasedCallback = Callback<Customer>
typealias PurchasedCallback = Callback<Customer>

typealias Milliseconds = Long
34 changes: 8 additions & 26 deletions sdk/src/main/java/com/apphud/sdk/client/ApphudClient.kt
Original file line number Diff line number Diff line change
Expand Up @@ -11,49 +11,31 @@ import com.apphud.sdk.mappers.ProductMapper
import com.apphud.sdk.mappers.SubscriptionMapper
import com.apphud.sdk.parser.Parser
import com.apphud.sdk.tasks.*
import java.util.concurrent.Executors
import java.util.concurrent.PriorityBlockingQueue
import java.util.concurrent.ThreadPoolExecutor
import java.util.concurrent.TimeUnit

internal class ApphudClient(apiKey: ApiKey, parser: Parser) {

companion object {
private const val capacity = 10
}

//TODO Про эти мапперы класс ApphudClient знать не должен
private val mapper = CustomerMapper(SubscriptionMapper())
private val productMapper = ProductMapper()
private val attributionMapper = AttributionMapper()

private val executor = HttpUrlConnectionExecutor(ApiClient.host, ApphudVersion.V1, parser)
private val thread = ThreadsUtils()
private val executor: NetworkExecutor = HttpUrlConnectionExecutor(ApiClient.host, ApphudVersion.V1, parser)
private val service = ApphudService(apiKey, executor)

private val queue = PriorityBlockingQueue<Runnable>(capacity, PriorityComparator())
private val pool = ThreadPoolExecutor(
1,
1,
0L,
TimeUnit.MILLISECONDS,
queue,
Executors.defaultThreadFactory(),
ThreadPoolExecutor.CallerRunsPolicy()
)

fun registrationUser(body: RegistrationBody, callback: CustomerCallback) {
val callable = RegistrationCallable(body, service)
pool.execute(LoopRunnable(callable) { response ->
thread.registration(callable) { response ->
when (response.data.results) {
null -> ApphudLog.log("Response success but result is null")
else -> callback.invoke(mapper.map(response.data.results))
}
})
}
}

fun allProducts(callback: ProductsCallback) {
val callable = ProductsCallable(service)
pool.execute(LoopRunnable(callable) { response ->
thread.allProducts(LoopRunnable(callable) { response ->
when (response.data.results) {
null -> ApphudLog.log("Response success but result is null")
else -> callback.invoke(response.data.results.map(productMapper::map))
Expand All @@ -63,7 +45,7 @@ internal class ApphudClient(apiKey: ApiKey, parser: Parser) {

fun send(body: AttributionBody, callback: AttributionCallback) {
val callable = AttributionCallable(body, service)
pool.execute(LoopRunnable(callable) { response ->
thread.execute(LoopRunnable(callable) { response ->
when (response.data.results) {
null -> ApphudLog.log("Response success but result is null")
else -> callback.invoke(attributionMapper.map(response.data.results))
Expand All @@ -73,7 +55,7 @@ internal class ApphudClient(apiKey: ApiKey, parser: Parser) {

fun send(body: PushBody, callback: AttributionCallback) {
val callable = PushCallable(body, service)
pool.execute(LoopRunnable(callable) { response ->
thread.execute(LoopRunnable(callable) { response ->
when (response.data.results) {
null -> ApphudLog.log("Response success but result is null")
else -> callback.invoke(attributionMapper.map(response.data.results))
Expand All @@ -83,7 +65,7 @@ internal class ApphudClient(apiKey: ApiKey, parser: Parser) {

fun purchased(body: PurchaseBody, callback: PurchasedCallback) {
val callable = PurchaseCallable(body, service)
pool.execute(LoopRunnable(callable) { response ->
thread.execute(LoopRunnable(callable) { response ->
when (response.data.results) {
null -> ApphudLog.log("Response success but result is null")
else -> callback.invoke(mapper.map(response.data.results))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ class HttpUrlConnectionExecutor(

connection.disconnect()

response ?: error("failed response")
response ?: exception(connection.responseCode)
} catch (e: Exception) {
when (e) {
is UnknownHostException,
Expand Down
5 changes: 5 additions & 0 deletions sdk/src/main/java/com/apphud/sdk/client/NetworkException.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.apphud.sdk.client

data class NetworkException(val code: Int) : RuntimeException()

internal fun exception(code: Int): Nothing = throw NetworkException(code)
38 changes: 38 additions & 0 deletions sdk/src/main/java/com/apphud/sdk/client/ThreadsUtils.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package com.apphud.sdk.client

import com.apphud.sdk.tasks.PriorityComparator
import java.util.concurrent.*

internal class ThreadsUtils {

companion object {
private const val capacity = 10
}

private var pool = buildExecutor()
private val service: ExecutorService = Executors.newSingleThreadExecutor()
private val unlimited: ExecutorService = Executors.newSingleThreadExecutor()

fun <T> registration(callable: Callable<T>, block: (T) -> Unit) =
service.execute {
try {
block.invoke(callable.call())
} catch (e: Exception) {
pool.shutdown()
pool = buildExecutor()
}
}

fun allProducts(runnable: Runnable) = unlimited.execute(runnable)
fun execute(runnable: Runnable) = pool.execute(runnable)

private fun buildExecutor() = ThreadPoolExecutor(
1,
1,
0L,
TimeUnit.MILLISECONDS,
PriorityBlockingQueue<Runnable>(capacity, PriorityComparator()),
Executors.defaultThreadFactory(),
ThreadPoolExecutor.CallerRunsPolicy()
)
}
4 changes: 1 addition & 3 deletions sdk/src/main/java/com/apphud/sdk/client/dto/CustomerDto.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ data class CustomerDto(
val id: String,
val user_id: String,
val locale: String,
val created_at: String,
val subscriptions: List<SubscriptionDto>,
val currency: CurrencyDto?,
val devices: List<DeviceDto>
val currency: CurrencyDto?
)
6 changes: 0 additions & 6 deletions sdk/src/main/java/com/apphud/sdk/client/dto/DeviceDto.kt

This file was deleted.

2 changes: 0 additions & 2 deletions sdk/src/main/java/com/apphud/sdk/client/dto/ProductDto.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,5 @@ package com.apphud.sdk.client.dto

data class ProductDto(
val id: String,
val db_id: String,
val group_id: String,
val product_id: String
)
6 changes: 6 additions & 0 deletions sdk/src/main/java/com/apphud/sdk/domain/AppsflyerInfo.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.apphud.sdk.domain

data class AppsflyerInfo(
val id: String?,
val data: Map<String, Any>?
)
5 changes: 5 additions & 0 deletions sdk/src/main/java/com/apphud/sdk/domain/FacebookInfo.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.apphud.sdk.domain

data class FacebookInfo(
val data: Map<String, Any>?
)
2 changes: 0 additions & 2 deletions sdk/src/main/java/com/apphud/sdk/domain/Product.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,5 @@ import com.apphud.sdk.ProductId

data class Product(
val id: String,
val dbId: String,
val groupId: String,
val productId: ProductId
)
6 changes: 2 additions & 4 deletions sdk/src/main/java/com/apphud/sdk/mappers/ProductMapper.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,9 @@ import com.apphud.sdk.domain.Product

class ProductMapper {

fun map(dto: ProductDto) : com.apphud.sdk.domain.Product =
com.apphud.sdk.domain.Product(
fun map(dto: ProductDto) : Product =
Product(
id = dto.id,
dbId = dto.db_id,
groupId = dto.group_id,
productId = dto.product_id
)
}
Loading

0 comments on commit 95d7261

Please sign in to comment.