Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(android): add keep rule for AndroidComposeView #1540

Merged
merged 2 commits into from
Nov 29, 2024
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
3 changes: 3 additions & 0 deletions android/measure/consumer-rules.pro
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,6 @@

# Required to check if androidx-fragment is present in runtime classpath
-keepnames class androidx.fragment.app.FragmentActivity

# Required to find gesture targe for composables
-keepnames class androidx.compose.ui.platform.AndroidComposeView
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ package sh.measure.android
import android.os.Build
import sh.measure.android.lifecycle.AppLifecycleListener
import sh.measure.android.logger.LogLevel
import java.util.concurrent.locks.ReentrantLock
import kotlin.concurrent.withLock

/**
* Initializes the Measure SDK and hides the internal dependencies from public API.
Expand Down Expand Up @@ -43,7 +41,7 @@ internal class MeasureInternal(measureInitializer: MeasureInitializer) : AppLife
private val dataCleanupService by lazy { measureInitializer.dataCleanupService }
private val powerStateProvider by lazy { measureInitializer.powerStateProvider }
private var isStarted: Boolean = false
private var startLock = ReentrantLock()
private var startLock = Any()

fun init() {
logger.log(LogLevel.Debug, "Starting Measure SDK")
Expand Down Expand Up @@ -77,7 +75,7 @@ internal class MeasureInternal(measureInitializer: MeasureInitializer) : AppLife
}

fun start() {
startLock.withLock {
synchronized(startLock) {
if (!isStarted) {
registerCollectors()
isStarted = true
Expand All @@ -86,7 +84,7 @@ internal class MeasureInternal(measureInitializer: MeasureInitializer) : AppLife
}

fun stop() {
startLock.withLock {
synchronized(startLock) {
if (isStarted) {
unregisterCollectors()
isStarted = false
Expand Down Expand Up @@ -124,7 +122,7 @@ internal class MeasureInternal(measureInitializer: MeasureInitializer) : AppLife
// session manager must be the first to be notified about app foreground to ensure that
// new session ID (if created) is reflected in all events collected after the launch.
sessionManager.onAppForeground()
startLock.withLock {
synchronized(startLock) {
if (isStarted) {
powerStateProvider.register()
networkChangesCollector.register()
Expand All @@ -137,7 +135,7 @@ internal class MeasureInternal(measureInitializer: MeasureInitializer) : AppLife

override fun onAppBackground() {
sessionManager.onAppBackground()
startLock.withLock {
synchronized(startLock) {
if (isStarted) {
cpuUsageCollector.pause()
memoryUsageCollector.pause()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ import java.util.concurrent.CopyOnWriteArrayList
import java.util.concurrent.Future
import java.util.concurrent.RejectedExecutionException
import java.util.concurrent.TimeUnit
import java.util.concurrent.locks.ReentrantLock
import kotlin.concurrent.withLock

internal interface HeartbeatListener {
fun pulse()
Expand All @@ -28,8 +26,8 @@ internal class HeartbeatImpl(
private val logger: Logger,
private val scheduler: MeasureExecutorService,
) : Heartbeat {
@Volatile
private var future: Future<*>? = null
private val lock = ReentrantLock()

@VisibleForTesting
internal val listeners = CopyOnWriteArrayList<HeartbeatListener>()
Expand All @@ -39,30 +37,26 @@ internal class HeartbeatImpl(
}

override fun start(intervalMs: Long, initialDelayMs: Long) {
lock.withLock {
if (future != null) {
return
}
try {
future = scheduler.scheduleAtFixedRate(
{
listeners.forEach(HeartbeatListener::pulse)
},
initialDelayMs,
intervalMs,
TimeUnit.MILLISECONDS,
)
} catch (e: RejectedExecutionException) {
logger.log(LogLevel.Error, "Failed to start ExportHeartbeat", e)
return
}
if (future != null) {
return
}
try {
future = scheduler.scheduleAtFixedRate(
{
listeners.forEach(HeartbeatListener::pulse)
},
initialDelayMs,
intervalMs,
TimeUnit.MILLISECONDS,
)
} catch (e: RejectedExecutionException) {
logger.log(LogLevel.Error, "Failed to start ExportHeartbeat", e)
return
}
}

override fun stop() {
lock.withLock {
future?.cancel(false)
future = null
}
future?.cancel(false)
future = null
}
}