diff --git a/android-core/src/main/java/com/mparticle/internal/BaseHandler.java b/android-core/src/main/java/com/mparticle/internal/BaseHandler.java deleted file mode 100644 index 455b80630..000000000 --- a/android-core/src/main/java/com/mparticle/internal/BaseHandler.java +++ /dev/null @@ -1,100 +0,0 @@ -package com.mparticle.internal; - -import android.os.Handler; -import android.os.Looper; -import android.os.Message; - -import com.mparticle.internal.listeners.InternalListenerManager; - -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.CountDownLatch; - -public class BaseHandler extends Handler { - private volatile boolean disabled; - private volatile boolean handling; - private ConcurrentHashMap messageQueue = new ConcurrentHashMap(); - - public Set getMessageQueue() { - return messageQueue.keySet(); - } - - public BaseHandler() { - } - - public BaseHandler(Looper looper) { - super(looper); - } - - public void disable(boolean disable) { - this.disabled = disable; - removeCallbacksAndMessages(null); - while (handling) { - } - } - - - public boolean isDisabled() { - return disabled; - } - - void await(CountDownLatch latch) { - this.sendMessage(obtainMessage(-1, latch)); - } - - @Override - public final void handleMessage(Message msg) { - if (disabled) { - Logger.error("Handler: " + getClass().getName() + " is destroyed! Message: \"" + msg.toString() + "\" will not be processed"); - return; - } - handling = true; - try { - if (msg != null) { - messageQueue.remove(msg); - } - if (msg != null && msg.what == -1 && msg.obj instanceof CountDownLatch) { - ((CountDownLatch) msg.obj).countDown(); - } else { - if (InternalListenerManager.isEnabled()) { - InternalListenerManager.getListener().onThreadMessage(getClass().getName(), msg, true); - } - try { - handleMessageImpl(msg); - } catch (OutOfMemoryError error) { - Logger.error("Out of memory"); - } - } - } finally { - handling = false; - } - } - - @Override - public boolean sendMessageAtTime(Message msg, long uptimeMillis) { - if (disabled) { - return false; - } - if (InternalListenerManager.isEnabled()) { - InternalListenerManager.getListener().onThreadMessage(getClass().getName(), msg, false); - } - if (msg != null) { - messageQueue.put(msg, true); - } - return super.sendMessageAtTime(msg, uptimeMillis); - } - - public void removeMessage(int what) { - Set messages = messageQueue.keySet(); - for (Message message : messages) { - if (message.what == what) { - messageQueue.remove(message); - } - } - super.removeMessages(what); - } - - //Override this in order to handle messages - public void handleMessageImpl(Message msg) { - } -} diff --git a/android-core/src/main/java/com/mparticle/internal/BaseHandler.kt b/android-core/src/main/java/com/mparticle/internal/BaseHandler.kt new file mode 100644 index 000000000..1646bf935 --- /dev/null +++ b/android-core/src/main/java/com/mparticle/internal/BaseHandler.kt @@ -0,0 +1,90 @@ +package com.mparticle.internal + +import android.os.Handler +import android.os.Looper +import android.os.Message +import com.mparticle.internal.listeners.InternalListenerManager.Companion.isEnabled +import com.mparticle.internal.listeners.InternalListenerManager.Companion.listener +import java.util.concurrent.ConcurrentHashMap +import java.util.concurrent.CountDownLatch + +open class BaseHandler : Handler { + @Volatile + var isDisabled: Boolean = false + private set + + @Volatile + private var handling = false + private val messageQueue: ConcurrentHashMap = ConcurrentHashMap() + + fun getMessageQueue(): Set { + return messageQueue.keys + } + + constructor() + + constructor(looper: Looper) : super(looper) + + fun disable(disable: Boolean) { + this.isDisabled = disable + removeCallbacksAndMessages(null) + while (handling) { + } + } + + fun await(latch: CountDownLatch?) { + this.sendMessage(obtainMessage(-1, latch)) + } + + override fun handleMessage(msg: Message) { + if (isDisabled) { + Logger.error("Handler: " + javaClass.name + " is destroyed! Message: \"" + msg.toString() + "\" will not be processed") + return + } + handling = true + try { + messageQueue.remove(msg) + if (msg.what == -1 && msg.obj is CountDownLatch) { + (msg.obj as CountDownLatch).countDown() + } else { + if (isEnabled) { + listener.onThreadMessage(javaClass.name, msg, true) + } + try { + handleMessageImpl(msg) + } catch (error: OutOfMemoryError) { + Logger.error("Out of memory") + } + } + } finally { + handling = false + } + } + + override fun sendMessageAtTime(msg: Message, uptimeMillis: Long): Boolean { + if (isDisabled) { + return false + } + if (isEnabled) { + listener.onThreadMessage(javaClass.name, msg, false) + } + + messageQueue[msg] = true + + return super.sendMessageAtTime(msg, uptimeMillis) + } + + fun removeMessage(what: Int) { + val messages: Set = messageQueue.keys + for (message in messages) { + if (message.what == what) { + messageQueue.remove(message) + } + } + super.removeMessages(what) + } + + // Override this in order to handle messages + open fun handleMessageImpl(msg: Message?) { + } +} diff --git a/android-core/src/test/kotlin/com/mparticle/internal/UploadHandlerTest.kt b/android-core/src/test/kotlin/com/mparticle/internal/UploadHandlerTest.kt index eb6d182ba..0360629f6 100644 --- a/android-core/src/test/kotlin/com/mparticle/internal/UploadHandlerTest.kt +++ b/android-core/src/test/kotlin/com/mparticle/internal/UploadHandlerTest.kt @@ -24,6 +24,7 @@ import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.mockito.Mockito +import org.mockito.stubbing.Answer import org.powermock.api.mockito.PowerMockito import org.powermock.core.classloader.annotations.PrepareForTest import org.powermock.modules.junit4.PowerMockRunner @@ -114,7 +115,15 @@ class UploadHandlerTest { @Test @Throws(Exception::class) fun testRampSampling() { - handler.handleMessage(Message()) + val message = Mockito.mock(Message::class.java) + + Mockito.`when`(message.toString()).thenAnswer( + Answer { + "Mocked Message" + } + ) + + handler.handleMessage(message) val apiClient = Mockito.mock( MParticleApiClientImpl::class.java )