Skip to content

Commit

Permalink
Merge branch 'refs/heads/master' into SUITEDEV-35599-MultiID-for-predict
Browse files Browse the repository at this point in the history
  • Loading branch information
megamegax committed Sep 5, 2024
2 parents 87a8260 + e4cd20e commit 1fdff70
Show file tree
Hide file tree
Showing 23 changed files with 168 additions and 173 deletions.
12 changes: 9 additions & 3 deletions changelog.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
# What's changed
### [Emarsys](https://github.com/emartech/android-emarsys-sdk/wiki#contents)
* Changed error handling in database operations to receive more detailed information.
# What's fixed

### [Geofence](https://github.com/emartech/android-emarsys-sdk/wiki#8-geofence)

* Fixed a compatibility issue with Android 14 (API level 34) and above.

### [In-App](https://github.com/emartech/android-emarsys-sdk/wiki#3-inapp)

* Fixed an edge-case when the Activity was not found for the given In-App message to display.
2 changes: 1 addition & 1 deletion core/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ dependencies {
implementation(libs.google.tink)
implementation(libs.kotlinx.coroutines.core)
implementation(libs.androidx.activity)

implementation(libs.startup.runtime)
androidTestImplementation(project(":testUtils"))

coreLibraryDesugaring(libs.android.tools.desugar)
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import android.content.SharedPreferences
import com.emarsys.core.CoreCompletionHandler
import com.emarsys.core.activity.ActivityLifecycleActionRegistry
import com.emarsys.core.activity.ActivityLifecycleWatchdog
import com.emarsys.core.activity.CurrentActivityWatchdog
import com.emarsys.core.activity.TransitionSafeCurrentActivityWatchdog
import com.emarsys.core.concurrency.ConcurrentHandlerHolderFactory
import com.emarsys.core.connection.ConnectionWatchDog
Expand Down Expand Up @@ -32,7 +31,6 @@ import org.mockito.kotlin.mock
class FakeCoreDependencyContainer(
override val concurrentHandlerHolder: ConcurrentHandlerHolder = ConcurrentHandlerHolderFactory.create(),
override val activityLifecycleWatchdog: ActivityLifecycleWatchdog = mock(),
override val currentActivityWatchdog: CurrentActivityWatchdog = mock(),
override val coreSQLiteDatabase: CoreSQLiteDatabase = mock(),
override val deviceInfo: DeviceInfo = mock(),
override val shardRepository: Repository<ShardModel, SqlSpecification> = mock(),
Expand Down
14 changes: 13 additions & 1 deletion core/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,18 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

<application>
<provider
android:name="androidx.startup.InitializationProvider"
android:authorities="${applicationId}.androidx-startup"
android:exported="false"
tools:node="merge">
<meta-data
android:name="com.emarsys.EmarsysSdkInitializer"
android:value="androidx.startup" />
</provider>
</application>
</manifest>
84 changes: 84 additions & 0 deletions core/src/main/java/com/emarsys/EmarsysSdkInitializer.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package com.emarsys

import android.app.Activity
import android.app.Application
import android.app.Application.ActivityLifecycleCallbacks
import android.content.Context
import android.os.Bundle
import androidx.startup.Initializer
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.launch
import java.lang.ref.WeakReference

internal var currentActivityFlow: MutableStateFlow<WeakReference<Activity?>?> =
MutableStateFlow(null)
private set

suspend fun getCurrentActivity(): Activity {
return currentActivityFlow.first { activity -> activity != null }!!.get()!!
}

class EmarsysSdkInitializer : Initializer<Unit> {
private val scope = CoroutineScope(SupervisorJob() + Dispatchers.Default)
private var setActivityJob: Job? = null

override fun create(context: Context) {
(context.applicationContext as Application).registerActivityLifecycleCallbacks(object :
ActivityLifecycleCallbacks {

override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {
currentActivityFlow.value = null
}

override fun onActivityStarted(activity: Activity) {
currentActivityFlow.value = null
}

override fun onActivityResumed(activity: Activity) {
setActivityJob = scope.launch {
delay(500)
currentActivityFlow.value = WeakReference(activity)
}
}

override fun onActivityPaused(activity: Activity) {
if (activity == currentActivityFlow.value) {
currentActivityFlow.value = null
setActivityJob?.cancel()
}
}

override fun onActivityStopped(activity: Activity) {
if (activity == currentActivityFlow.value) {
currentActivityFlow.value = null
setActivityJob?.cancel()
}
}

override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {
if (activity == currentActivityFlow.value) {
currentActivityFlow.value = null
setActivityJob?.cancel()
}
}

override fun onActivityDestroyed(activity: Activity) {
if (activity == currentActivityFlow.value) {
currentActivityFlow.value = null
setActivityJob?.cancel()
}
}
})
}

override fun dependencies(): List<Class<out Initializer<*>>> {
return emptyList()
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -6,67 +6,77 @@ import android.os.Bundle
import com.emarsys.core.Mockable
import com.emarsys.core.handler.SdkHandler
import com.emarsys.core.observer.Observer
import com.emarsys.core.provider.Property
import com.emarsys.getCurrentActivity
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import java.util.concurrent.CountDownLatch

@Mockable
class TransitionSafeCurrentActivityWatchdog(private val handler: SdkHandler) :
class TransitionSafeCurrentActivityWatchdog(
private val handler: SdkHandler,
private val currentActivityProvider: Property<Activity?>
) :
ActivityLifecycleCallbacks, Observer<Activity> {

private val activityCallbacks = mutableListOf<(Activity) -> Unit>()

private var currentActivity: Activity? = null
private var mCurrentActivity: Activity? = null

private val callback: Runnable = Runnable {
if (currentActivity != null) {
notify(currentActivity!!)
if (mCurrentActivity != null) {
notify(mCurrentActivity!!)
}
}

override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {
currentActivity = null
mCurrentActivity = null
}

override fun onActivityStarted(activity: Activity) {
currentActivity = null
mCurrentActivity = null
}

override fun onActivityResumed(activity: Activity) {
currentActivity = activity
mCurrentActivity = activity
handler.postDelayed(callback, 500)
}

override fun onActivityPaused(activity: Activity) {
if (activity == currentActivity) {
currentActivity = null
if (activity == mCurrentActivity) {
mCurrentActivity = null
handler.remove(callback)
}
}

override fun onActivityStopped(activity: Activity) {
if (activity == currentActivity) {
currentActivity = null
if (activity == mCurrentActivity) {
mCurrentActivity = null
handler.remove(callback)
}
}

override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {
if (activity == currentActivity) {
currentActivity = null
if (activity == mCurrentActivity) {
mCurrentActivity = null
handler.remove(callback)
}
}

override fun onActivityDestroyed(activity: Activity) {
if (activity == currentActivity) {
currentActivity = null
if (activity == mCurrentActivity) {
mCurrentActivity = null
handler.remove(callback)
}
}

override fun register(callback: (Activity) -> Unit) {
activityCallbacks.add(callback)
if (currentActivity != null) {
callback(currentActivity!!)
CoroutineScope(Dispatchers.Default).launch {
val currentActivity = getCurrentActivity()
currentActivityProvider.set(currentActivity)
callback(currentActivity)
}
}

Expand All @@ -75,10 +85,14 @@ class TransitionSafeCurrentActivityWatchdog(private val handler: SdkHandler) :
}

override fun notify(value: Activity) {
currentActivityProvider.set(value)
activityCallbacks.forEach { it(value) }
}

fun activity(): Activity {
if (mCurrentActivity != null) {
return mCurrentActivity!!
}
lateinit var result: Activity
val latch = CountDownLatch(1)
val callback: (Activity) -> Unit = {
Expand Down
3 changes: 0 additions & 3 deletions core/src/main/java/com/emarsys/core/di/CoreComponent.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import android.content.SharedPreferences
import com.emarsys.core.CoreCompletionHandler
import com.emarsys.core.activity.ActivityLifecycleActionRegistry
import com.emarsys.core.activity.ActivityLifecycleWatchdog
import com.emarsys.core.activity.CurrentActivityWatchdog
import com.emarsys.core.activity.TransitionSafeCurrentActivityWatchdog
import com.emarsys.core.connection.ConnectionWatchDog
import com.emarsys.core.crypto.Crypto
Expand Down Expand Up @@ -53,8 +52,6 @@ interface CoreComponent {

val activityLifecycleWatchdog: ActivityLifecycleWatchdog

val currentActivityWatchdog: CurrentActivityWatchdog

val activityLifecycleActionRegistry: ActivityLifecycleActionRegistry

val coreSQLiteDatabase: CoreSQLiteDatabase
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ object E2ETestUtils {
emarsys().concurrentHandlerHolder.coreHandler.post {
if (application != null) {
application.unregisterActivityLifecycleCallbacks(emarsys().activityLifecycleWatchdog)
application.unregisterActivityLifecycleCallbacks(emarsys().currentActivityWatchdog)
application.unregisterActivityLifecycleCallbacks(emarsys().transitionSafeCurrentActivityWatchdog)
}

emarsys().contactTokenStorage.remove()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import android.content.SharedPreferences
import com.emarsys.core.CoreCompletionHandler
import com.emarsys.core.activity.ActivityLifecycleActionRegistry
import com.emarsys.core.activity.ActivityLifecycleWatchdog
import com.emarsys.core.activity.CurrentActivityWatchdog
import com.emarsys.core.activity.TransitionSafeCurrentActivityWatchdog
import com.emarsys.core.app.AppLifecycleObserver
import com.emarsys.core.concurrency.ConcurrentHandlerHolderFactory
Expand Down Expand Up @@ -124,7 +123,6 @@ class FakeFirebaseDependencyContainer(
override val mobileEngageRequestModelFactory: MobileEngageRequestModelFactory = mock(),
override val mobileEngageSession: MobileEngageSession = mock(),
override val activityLifecycleWatchdog: ActivityLifecycleWatchdog = mock(),
override val currentActivityWatchdog: CurrentActivityWatchdog = mock(),
override val coreSQLiteDatabase: CoreSQLiteDatabase = mock(),
override val deviceInfo: DeviceInfo = mock(),
override val shardRepository: Repository<ShardModel, SqlSpecification> = mock(),
Expand Down
Loading

0 comments on commit 1fdff70

Please sign in to comment.