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

chore: java sdk based on the android core sdk #129

Draft
wants to merge 13 commits into
base: main
Choose a base branch
from
Draft
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
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ tasks.withType<DetektCreateBaselineTask>().configureEach {
}

apiValidation {
ignoredProjects.add("posthog-android-sample")
ignoredProjects.addAll(listOf("posthog-android-sample", "posthog-console-sample"))
}

nexusPublishing.postHogConfig()
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,14 @@ public open class PostHogAndroidConfig(
public var captureScreenViews: Boolean = true,
@PostHogExperimental
public var sessionReplayConfig: PostHogSessionReplayConfig = PostHogSessionReplayConfig(),
) : PostHogConfig(apiKey, host)
) : PostHogConfig(apiKey, host) {
init {
isClientSDK = true
featureFlagsRequestTimeoutSeconds = 10
flushAt = 20
maxQueueSize = 1000
maxBatchSize = 50
disableGeoIP = false
preloadFeatureFlags = true
Comment on lines +24 to +30
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Those are the defaults for Android

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ import android.os.Build
import android.util.DisplayMetrics
import com.posthog.android.PostHogAndroidConfig
import com.posthog.internal.PostHogContext
import java.util.Locale
import java.util.TimeZone
import kotlin.math.pow
import kotlin.math.sqrt

Expand Down Expand Up @@ -141,11 +139,6 @@ internal class PostHogAndroidContext(
@SuppressLint("MissingPermission")
override fun getDynamicContext(): Map<String, Any> {
val dynamicContext = mutableMapOf<String, Any>()
dynamicContext["\$locale"] = "${Locale.getDefault().language}-${Locale.getDefault().country}"
System.getProperty("http.agent")?.let {
dynamicContext["\$user_agent"] = it
}
dynamicContext["\$timezone"] = TimeZone.getDefault().id

context.connectivityManager()?.let { connectivityManager ->
if (context.hasPermission(Manifest.permission.ACCESS_NETWORK_STATE)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public class PostHogFake : PostHogInterface {
properties: Map<String, Any>?,
userProperties: Map<String, Any>?,
userPropertiesSetOnce: Map<String, Any>?,
groupProperties: Map<String, Any>?,
groups: Map<String, Any>?,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if this should have been Map<String, String> since group(type: String, key: String) are Strings only

) {
this.event = event
this.properties = properties
Expand All @@ -42,24 +42,44 @@ public class PostHogFake : PostHogInterface {
override fun isFeatureEnabled(
key: String,
defaultValue: Boolean,
distinctId: String?,
groups: Map<String, Any>?,
): Boolean {
return false
}

override fun getFeatureFlag(
key: String,
defaultValue: Any?,
distinctId: String?,
groups: Map<String, Any>?,
): Any? {
return null
}

override fun getFeatureFlagPayload(
key: String,
defaultValue: Any?,
distinctId: String?,
groups: Map<String, Any>?,
): Any? {
return null
}

override fun getAllFeatureFlags(
distinctId: String?,
groups: Map<String, Any>?,
): Map<String, Any>? {
return null
}

override fun getAllFeatureFlagsAndPayloads(
distinctId: String?,
groups: Map<String, Any>?,
): Pair<Map<String, Any>?, Map<String, Any?>?> {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a big fan of Pair, but returning a map with 2 keys like in python:
return {"featureFlags": None, "featureFlagPayloads": None} isn't ideal either, people would need to know the key.

return Pair(null, null)
}

override fun flush() {
}

Expand All @@ -76,17 +96,22 @@ public class PostHogFake : PostHogInterface {
type: String,
key: String,
groupProperties: Map<String, Any>?,
distinctId: String?,
Copy link
Member Author

@marandaneto marandaneto May 7, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

distinctId is optional for Android since its cached in the disk/memory and required for Java, this has to be over documentation/method docs, otherwise I'd need to create another class (PostHogAndroid, PostHogJava, PostHogCore) and dupe a lot of code just because of this facility, is it worth it?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"is it worth it"... 🤔

it's a dev experience question I guess....

what does it mean for what I have to type?
what does it mean for how easy it is to make a mistake?
if i make a mistake how do I find out? will i get helpful errors

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you call capture without distinctId on a Java backend app, it'll log in the console:

PostHog.capture("event")
vs
PostHog.capture("event", distinctId = "123")

"capture call not allowed, distinctId is invalid: $var."

I agree, I also prefer better dev UX but since both libs (core and Android) share the same interface, this is the issue we get hence my comment above.
If we prioritize better dev UX having an interface each lib we'd need to make major breaking changes, so we'd need to cut Android v4 as well, I was not aware or was an oversight from my side that distinctId has to be always passed during capture calls on Java since its stateless, this could be solved with scope management - thread local storage (if you set distinctId on thread/request X its always X, etc) but that's another big change not intended to be done now anyway.

) {
}

override fun screen(
screenTitle: String,
properties: Map<String, Any>?,
distinctId: String?,
) {
this.screenTitle = screenTitle
}

override fun alias(alias: String) {
override fun alias(
alias: String,
distinctId: String?,
) {
}

override fun isOptOut(): Boolean {
Expand Down
25 changes: 25 additions & 0 deletions posthog-samples/posthog-console-sample/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins {
kotlin("jvm")
}

group = "com.posthog"
version = "1.0.0"

dependencies {
implementation(project(mapOf("path" to ":posthog")))
testImplementation(kotlin("test"))
}

tasks.test {
useJUnitPlatform()
}

tasks.withType<KotlinCompile>().configureEach {
kotlinOptions.postHogConfig()
}

kotlin {
jvmToolchain(PosthogBuildConfig.Build.JAVA_VERSION.majorVersion.toInt())
}
36 changes: 36 additions & 0 deletions posthog-samples/posthog-console-sample/src/main/java/Main.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.posthog

import java.lang.Thread.sleep

public fun main() {
val config =
PostHogConfig("phc_pQ70jJhZKHRvDIL5ruOErnPy6xiAiWCqlL4ayELj4X8").apply {
debug = true
flushAt = 1
}
PostHog.setup(config)

PostHog.capture(
event = "Hello World!",
distinctId = "123",
properties = mapOf("test" to true),
userProperties = mapOf("name" to "my name"),
userPropertiesSetOnce = mapOf("age" to 33),
groups = mapOf("company" to "posthog"),
)
PostHog.isFeatureEnabled(
"myFlag",
defaultValue = false,
distinctId = "123",
groups = mapOf("company" to "posthog"),
)

PostHog.flush()
//
PostHog.close()

while (Thread.activeCount() > 1) {
println("threads still active")
sleep(10000)
}
}
67 changes: 42 additions & 25 deletions posthog/api/posthog.api
Original file line number Diff line number Diff line change
@@ -1,46 +1,50 @@
public final class com/posthog/PostHog : com/posthog/PostHogInterface {
public static final field Companion Lcom/posthog/PostHog$Companion;
public synthetic fun <init> (Ljava/util/concurrent/ExecutorService;Ljava/util/concurrent/ExecutorService;Ljava/util/concurrent/ExecutorService;Ljava/util/concurrent/ExecutorService;ZLkotlin/jvm/internal/DefaultConstructorMarker;)V
public fun alias (Ljava/lang/String;)V
public fun alias (Ljava/lang/String;Ljava/lang/String;)V
public fun capture (Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;Ljava/util/Map;Ljava/util/Map;Ljava/util/Map;)V
public fun close ()V
public fun debug (Z)V
public fun distinctId ()Ljava/lang/String;
public fun endSession ()V
public fun flush ()V
public fun getAllFeatureFlags (Ljava/lang/String;Ljava/util/Map;)Ljava/util/Map;
public fun getAllFeatureFlagsAndPayloads (Ljava/lang/String;Ljava/util/Map;)Lkotlin/Pair;
public fun getConfig ()Lcom/posthog/PostHogConfig;
public fun getFeatureFlag (Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object;
public fun getFeatureFlagPayload (Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object;
public fun group (Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;)V
public fun getFeatureFlag (Ljava/lang/String;Ljava/lang/Object;Ljava/lang/String;Ljava/util/Map;)Ljava/lang/Object;
public fun getFeatureFlagPayload (Ljava/lang/String;Ljava/lang/Object;Ljava/lang/String;Ljava/util/Map;)Ljava/lang/Object;
public fun group (Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;Ljava/lang/String;)V
public fun identify (Ljava/lang/String;Ljava/util/Map;Ljava/util/Map;)V
public fun isFeatureEnabled (Ljava/lang/String;Z)Z
public fun isFeatureEnabled (Ljava/lang/String;ZLjava/lang/String;Ljava/util/Map;)Z
public fun isOptOut ()Z
public fun isSessionActive ()Z
public fun optIn ()V
public fun optOut ()V
public fun register (Ljava/lang/String;Ljava/lang/Object;)V
public fun reloadFeatureFlags (Lcom/posthog/PostHogOnFeatureFlags;)V
public fun reset ()V
public fun screen (Ljava/lang/String;Ljava/util/Map;)V
public fun screen (Ljava/lang/String;Ljava/util/Map;Ljava/lang/String;)V
public fun setup (Lcom/posthog/PostHogConfig;)V
public fun startSession ()V
public fun unregister (Ljava/lang/String;)V
}

public final class com/posthog/PostHog$Companion : com/posthog/PostHogInterface {
public fun alias (Ljava/lang/String;)V
public fun alias (Ljava/lang/String;Ljava/lang/String;)V
public fun capture (Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;Ljava/util/Map;Ljava/util/Map;Ljava/util/Map;)V
public fun close ()V
public fun debug (Z)V
public fun distinctId ()Ljava/lang/String;
public fun endSession ()V
public fun flush ()V
public fun getAllFeatureFlags (Ljava/lang/String;Ljava/util/Map;)Ljava/util/Map;
public fun getAllFeatureFlagsAndPayloads (Ljava/lang/String;Ljava/util/Map;)Lkotlin/Pair;
public fun getConfig ()Lcom/posthog/PostHogConfig;
public fun getFeatureFlag (Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object;
public fun getFeatureFlagPayload (Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object;
public fun group (Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;)V
public fun getFeatureFlag (Ljava/lang/String;Ljava/lang/Object;Ljava/lang/String;Ljava/util/Map;)Ljava/lang/Object;
public fun getFeatureFlagPayload (Ljava/lang/String;Ljava/lang/Object;Ljava/lang/String;Ljava/util/Map;)Ljava/lang/Object;
public fun group (Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;Ljava/lang/String;)V
public fun identify (Ljava/lang/String;Ljava/util/Map;Ljava/util/Map;)V
public fun isFeatureEnabled (Ljava/lang/String;Z)Z
public fun isFeatureEnabled (Ljava/lang/String;ZLjava/lang/String;Ljava/util/Map;)Z
public fun isOptOut ()Z
public fun isSessionActive ()Z
public fun optIn ()V
Expand All @@ -50,7 +54,7 @@ public final class com/posthog/PostHog$Companion : com/posthog/PostHogInterface
public fun reloadFeatureFlags (Lcom/posthog/PostHogOnFeatureFlags;)V
public fun reset ()V
public final fun resetSharedInstance ()V
public fun screen (Ljava/lang/String;Ljava/util/Map;)V
public fun screen (Ljava/lang/String;Ljava/util/Map;Ljava/lang/String;)V
public fun setup (Lcom/posthog/PostHogConfig;)V
public fun startSession ()V
public fun unregister (Ljava/lang/String;)V
Expand All @@ -60,15 +64,17 @@ public final class com/posthog/PostHog$Companion : com/posthog/PostHogInterface
public class com/posthog/PostHogConfig {
public static final field Companion Lcom/posthog/PostHogConfig$Companion;
public static final field DEFAULT_HOST Ljava/lang/String;
public fun <init> (Ljava/lang/String;Ljava/lang/String;ZZZZIIIILcom/posthog/PostHogEncryption;Lcom/posthog/PostHogOnFeatureFlags;ZLcom/posthog/PostHogPropertiesSanitizer;)V
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/String;ZZZZIIIILcom/posthog/PostHogEncryption;Lcom/posthog/PostHogOnFeatureFlags;ZLcom/posthog/PostHogPropertiesSanitizer;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public fun <init> (Ljava/lang/String;Ljava/lang/String;ZZZZIIIILcom/posthog/PostHogEncryption;Lcom/posthog/PostHogOnFeatureFlags;ZLcom/posthog/PostHogPropertiesSanitizer;IIZ)V
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/String;ZZZZIIIILcom/posthog/PostHogEncryption;Lcom/posthog/PostHogOnFeatureFlags;ZLcom/posthog/PostHogPropertiesSanitizer;IIZILkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun addIntegration (Lcom/posthog/PostHogIntegration;)V
public final fun getApiKey ()Ljava/lang/String;
public final fun getCachePreferences ()Lcom/posthog/internal/PostHogPreferences;
public final fun getContext ()Lcom/posthog/internal/PostHogContext;
public final fun getDateProvider ()Lcom/posthog/internal/PostHogDateProvider;
public final fun getDebug ()Z
public final fun getDisableGeoIP ()Z
public final fun getEncryption ()Lcom/posthog/PostHogEncryption;
public final fun getFeatureFlagsRequestTimeoutSeconds ()I
public final fun getFlushAt ()I
public final fun getFlushIntervalSeconds ()I
public final fun getHost ()Ljava/lang/String;
Expand All @@ -83,19 +89,24 @@ public class com/posthog/PostHogConfig {
public final fun getPreloadFeatureFlags ()Z
public final fun getPropertiesSanitizer ()Lcom/posthog/PostHogPropertiesSanitizer;
public final fun getReplayStoragePrefix ()Ljava/lang/String;
public final fun getRequestTimeoutSeconds ()I
public final fun getSdkName ()Ljava/lang/String;
public final fun getSdkVersion ()Ljava/lang/String;
public final fun getSendFeatureFlagEvent ()Z
public final fun getSerializer ()Lcom/posthog/internal/PostHogSerializer;
public final fun getSessionReplay ()Z
public final fun getSnapshotEndpoint ()Ljava/lang/String;
public final fun getStoragePrefix ()Ljava/lang/String;
public final fun isClientSDK ()Z
public final fun removeIntegration (Lcom/posthog/PostHogIntegration;)V
public final fun setCachePreferences (Lcom/posthog/internal/PostHogPreferences;)V
public final fun setClientSDK (Z)V
public final fun setContext (Lcom/posthog/internal/PostHogContext;)V
public final fun setDateProvider (Lcom/posthog/internal/PostHogDateProvider;)V
public final fun setDebug (Z)V
public final fun setDisableGeoIP (Z)V
public final fun setEncryption (Lcom/posthog/PostHogEncryption;)V
public final fun setFeatureFlagsRequestTimeoutSeconds (I)V
public final fun setFlushAt (I)V
public final fun setFlushIntervalSeconds (I)V
public final fun setLegacyStoragePrefix (Ljava/lang/String;)V
Expand All @@ -108,6 +119,7 @@ public class com/posthog/PostHogConfig {
public final fun setPreloadFeatureFlags (Z)V
public final fun setPropertiesSanitizer (Lcom/posthog/PostHogPropertiesSanitizer;)V
public final fun setReplayStoragePrefix (Ljava/lang/String;)V
public final fun setRequestTimeoutSeconds (I)V
public final fun setSdkName (Ljava/lang/String;)V
public final fun setSdkVersion (Ljava/lang/String;)V
public final fun setSendFeatureFlagEvent (Z)V
Expand Down Expand Up @@ -166,42 +178,47 @@ public final class com/posthog/PostHogIntegration$DefaultImpls {
}

public abstract interface class com/posthog/PostHogInterface {
public abstract fun alias (Ljava/lang/String;)V
public abstract fun alias (Ljava/lang/String;Ljava/lang/String;)V
public abstract fun capture (Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;Ljava/util/Map;Ljava/util/Map;Ljava/util/Map;)V
public abstract fun close ()V
public abstract fun debug (Z)V
public abstract fun distinctId ()Ljava/lang/String;
public abstract fun endSession ()V
public abstract fun flush ()V
public abstract fun getAllFeatureFlags (Ljava/lang/String;Ljava/util/Map;)Ljava/util/Map;
public abstract fun getAllFeatureFlagsAndPayloads (Ljava/lang/String;Ljava/util/Map;)Lkotlin/Pair;
public abstract fun getConfig ()Lcom/posthog/PostHogConfig;
public abstract fun getFeatureFlag (Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object;
public abstract fun getFeatureFlagPayload (Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object;
public abstract fun group (Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;)V
public abstract fun getFeatureFlag (Ljava/lang/String;Ljava/lang/Object;Ljava/lang/String;Ljava/util/Map;)Ljava/lang/Object;
public abstract fun getFeatureFlagPayload (Ljava/lang/String;Ljava/lang/Object;Ljava/lang/String;Ljava/util/Map;)Ljava/lang/Object;
public abstract fun group (Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;Ljava/lang/String;)V
public abstract fun identify (Ljava/lang/String;Ljava/util/Map;Ljava/util/Map;)V
public abstract fun isFeatureEnabled (Ljava/lang/String;Z)Z
public abstract fun isFeatureEnabled (Ljava/lang/String;ZLjava/lang/String;Ljava/util/Map;)Z
public abstract fun isOptOut ()Z
public abstract fun isSessionActive ()Z
public abstract fun optIn ()V
public abstract fun optOut ()V
public abstract fun register (Ljava/lang/String;Ljava/lang/Object;)V
public abstract fun reloadFeatureFlags (Lcom/posthog/PostHogOnFeatureFlags;)V
public abstract fun reset ()V
public abstract fun screen (Ljava/lang/String;Ljava/util/Map;)V
public abstract fun screen (Ljava/lang/String;Ljava/util/Map;Ljava/lang/String;)V
public abstract fun setup (Lcom/posthog/PostHogConfig;)V
public abstract fun startSession ()V
public abstract fun unregister (Ljava/lang/String;)V
}

public final class com/posthog/PostHogInterface$DefaultImpls {
public static synthetic fun alias$default (Lcom/posthog/PostHogInterface;Ljava/lang/String;Ljava/lang/String;ILjava/lang/Object;)V
public static synthetic fun capture$default (Lcom/posthog/PostHogInterface;Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;Ljava/util/Map;Ljava/util/Map;Ljava/util/Map;ILjava/lang/Object;)V
public static synthetic fun debug$default (Lcom/posthog/PostHogInterface;ZILjava/lang/Object;)V
public static synthetic fun getFeatureFlag$default (Lcom/posthog/PostHogInterface;Ljava/lang/String;Ljava/lang/Object;ILjava/lang/Object;)Ljava/lang/Object;
public static synthetic fun getFeatureFlagPayload$default (Lcom/posthog/PostHogInterface;Ljava/lang/String;Ljava/lang/Object;ILjava/lang/Object;)Ljava/lang/Object;
public static synthetic fun group$default (Lcom/posthog/PostHogInterface;Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;ILjava/lang/Object;)V
public static synthetic fun getAllFeatureFlags$default (Lcom/posthog/PostHogInterface;Ljava/lang/String;Ljava/util/Map;ILjava/lang/Object;)Ljava/util/Map;
public static synthetic fun getAllFeatureFlagsAndPayloads$default (Lcom/posthog/PostHogInterface;Ljava/lang/String;Ljava/util/Map;ILjava/lang/Object;)Lkotlin/Pair;
public static synthetic fun getFeatureFlag$default (Lcom/posthog/PostHogInterface;Ljava/lang/String;Ljava/lang/Object;Ljava/lang/String;Ljava/util/Map;ILjava/lang/Object;)Ljava/lang/Object;
public static synthetic fun getFeatureFlagPayload$default (Lcom/posthog/PostHogInterface;Ljava/lang/String;Ljava/lang/Object;Ljava/lang/String;Ljava/util/Map;ILjava/lang/Object;)Ljava/lang/Object;
public static synthetic fun group$default (Lcom/posthog/PostHogInterface;Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;Ljava/lang/String;ILjava/lang/Object;)V
public static synthetic fun identify$default (Lcom/posthog/PostHogInterface;Ljava/lang/String;Ljava/util/Map;Ljava/util/Map;ILjava/lang/Object;)V
public static synthetic fun isFeatureEnabled$default (Lcom/posthog/PostHogInterface;Ljava/lang/String;ZILjava/lang/Object;)Z
public static synthetic fun isFeatureEnabled$default (Lcom/posthog/PostHogInterface;Ljava/lang/String;ZLjava/lang/String;Ljava/util/Map;ILjava/lang/Object;)Z
public static synthetic fun reloadFeatureFlags$default (Lcom/posthog/PostHogInterface;Lcom/posthog/PostHogOnFeatureFlags;ILjava/lang/Object;)V
public static synthetic fun screen$default (Lcom/posthog/PostHogInterface;Ljava/lang/String;Ljava/util/Map;ILjava/lang/Object;)V
public static synthetic fun screen$default (Lcom/posthog/PostHogInterface;Ljava/lang/String;Ljava/util/Map;Ljava/lang/String;ILjava/lang/Object;)V
}

public abstract interface annotation class com/posthog/PostHogInternal : java/lang/annotation/Annotation {
Expand Down
Loading
Loading