Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package com.mindboxsdk

import android.os.Bundle
import android.util.Log
import cloud.mindbox.mobile_sdk.pushes.MindboxPushService

internal class MindboxPushServicesDiscovery(private val meta: Bundle?) {

companion object {
private const val TAG = "MindboxPushServicesDiscovery"
private const val PUSH_PROVIDER_PREFIX = "cloud.mindbox.push.provider."
}

private val providerPriority: Map<String, Int> by lazy(LazyThreadSafetyMode.NONE) {
mapOf("FCM" to 0, "HCM" to 1, "RuStore" to 2)
}

val services: List<MindboxPushService> by lazy(LazyThreadSafetyMode.NONE) {
if (meta == null) {
return@lazy emptyList()
}
meta.keySet()
.asSequence()
.filter { it.startsWith(PUSH_PROVIDER_PREFIX) }
.mapNotNull { key -> meta.getString(key)?.takeIf { it.isNotBlank() } }
.mapNotNull { className -> loadPushService(className) }
.distinctBy { it::class.java.name }
.sortedWith(
compareBy<MindboxPushService> { providerPriority[it.tag] ?: Int.MAX_VALUE }
.thenBy { it.tag }
)
.toList()
.also { list ->
Log.i(TAG, "Found ${list.size} push services: ${list.joinToString { it.tag }}")
list
}
}

private fun loadPushService(className: String): MindboxPushService? {
return runCatching {
val clazz = Class.forName(className)

if (!MindboxPushService::class.java.isAssignableFrom(clazz)) {
Log.w(TAG, "Class $className does not implement MindboxPushService")
return@runCatching null
}
getPushServiceInstance(clazz)?.also {
Log.i(TAG, "Loaded push provider: $className")
} ?: run {
Log.e(TAG, "Failed to create instance for provider: $className")
null
}
}.getOrElse { exception ->
when (exception) {
is ClassNotFoundException -> Log.e(TAG, "Push provider class not found: $className", exception)
else -> Log.e(TAG, "Failed to load push provider: $className", exception)
}
null
}
}

private fun getPushServiceInstance(clazz: Class<*>): MindboxPushService? {
return runCatching {
val instanceField = clazz.getDeclaredField("INSTANCE")
instanceField.isAccessible = true
instanceField.get(null) as? MindboxPushService
}.getOrElse {
Log.w(TAG, "Failed to get instance for ${clazz.name}")
null
}
}
}
26 changes: 14 additions & 12 deletions android/src/main/java/com/mindboxsdk/MindboxSdkInitProvider.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ import android.content.ContentValues
import android.content.pm.PackageManager
import android.database.Cursor
import android.net.Uri
import android.os.Bundle
import android.util.Log
import cloud.mindbox.mobile_sdk.pushes.MindboxPushService
import cloud.mindbox.mobile_sdk.Mindbox

internal class MindboxSdkInitProvider : ContentProvider() {

Expand All @@ -19,8 +22,10 @@ internal class MindboxSdkInitProvider : ContentProvider() {
runCatching {
Log.i(TAG, "onCreate initProvider.")
(context?.applicationContext as? Application)?.let { application ->
if (isAutoInitEnabled(application)) {
val meta = application.readMetaData()
if (isAutoInitEnabled(application, meta)) {
Log.i(TAG, "Automatic initialization is enabled.")
Mindbox.initPushServices(application, MindboxPushServicesDiscovery(meta).services)
MindboxSdkLifecycleListener.register(application)
} else {
Log.i(TAG, "Automatic initialization is disabled.")
Expand All @@ -32,17 +37,14 @@ internal class MindboxSdkInitProvider : ContentProvider() {
return true
}

private fun isAutoInitEnabled(application: Application): Boolean =
runCatching {
val appInfo = application.packageManager.getApplicationInfo(
application.packageName,
PackageManager.GET_META_DATA
)
appInfo.metaData
?.getBoolean(AUTO_INIT_ENABLED_KEY, false)
?.also { Log.i(TAG, "Result of reading mindbox metadata is $it") }
?: false
}.getOrElse { false }
private fun isAutoInitEnabled(application: Application, metaData: Bundle?): Boolean =
metaData
?.getBoolean(AUTO_INIT_ENABLED_KEY, false)
?: false

private fun Application.readMetaData(): Bundle? = runCatching {
packageManager.getApplicationInfo(packageName, PackageManager.GET_META_DATA).metaData
}.getOrNull()

override fun query(
uri: Uri,
Expand Down