From 550e2202b7485b372c20510b35103890424a04d2 Mon Sep 17 00:00:00 2001 From: Rehan Date: Fri, 13 Dec 2024 20:23:48 +0500 Subject: [PATCH 1/5] feat: screen view usage --- datapipelines/api/datapipelines.api | 38 +++++++++- .../config/DataPipelinesModuleConfig.kt | 4 +- .../datapipelines/config/ScreenView.kt | 28 ++++++++ .../plugins/ScreenFilterPlugin.kt | 27 +++++++ .../main/kotlin/io/customer/sdk/CustomerIO.kt | 4 ++ .../io/customer/sdk/CustomerIOBuilder.kt | 17 ++++- .../plugins/ScreenFilterPluginTest.kt | 72 +++++++++++++++++++ .../sdk/CustomerIOBuilderTest.kt | 13 ++++ 8 files changed, 199 insertions(+), 4 deletions(-) create mode 100644 datapipelines/src/main/kotlin/io/customer/datapipelines/config/ScreenView.kt create mode 100644 datapipelines/src/main/kotlin/io/customer/datapipelines/plugins/ScreenFilterPlugin.kt create mode 100644 datapipelines/src/test/java/io/customer/datapipelines/plugins/ScreenFilterPluginTest.kt diff --git a/datapipelines/api/datapipelines.api b/datapipelines/api/datapipelines.api index 6f725ed55..ab9612960 100644 --- a/datapipelines/api/datapipelines.api +++ b/datapipelines/api/datapipelines.api @@ -1,6 +1,6 @@ public final class io/customer/datapipelines/config/DataPipelinesModuleConfig : io/customer/sdk/core/module/CustomerIOModuleConfig { - public fun (Ljava/lang/String;Lio/customer/sdk/data/model/Region;Ljava/lang/String;Ljava/lang/String;IILjava/util/List;ZZZZLjava/lang/String;)V - public synthetic fun (Ljava/lang/String;Lio/customer/sdk/data/model/Region;Ljava/lang/String;Ljava/lang/String;IILjava/util/List;ZZZZLjava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun (Ljava/lang/String;Lio/customer/sdk/data/model/Region;Ljava/lang/String;Ljava/lang/String;IILjava/util/List;ZZZZLjava/lang/String;Lio/customer/datapipelines/config/ScreenView;)V + public synthetic fun (Ljava/lang/String;Lio/customer/sdk/data/model/Region;Ljava/lang/String;Ljava/lang/String;IILjava/util/List;ZZZZLjava/lang/String;Lio/customer/datapipelines/config/ScreenView;ILkotlin/jvm/internal/DefaultConstructorMarker;)V public final fun getApiHost ()Ljava/lang/String; public final fun getAutoAddCustomerIODestination ()Z public final fun getAutoTrackActivityScreens ()Z @@ -11,9 +11,24 @@ public final class io/customer/datapipelines/config/DataPipelinesModuleConfig : public final fun getFlushInterval ()I public final fun getFlushPolicies ()Ljava/util/List; public final fun getMigrationSiteId ()Ljava/lang/String; + public final fun getScreenViewUse ()Lio/customer/datapipelines/config/ScreenView; public final fun getTrackApplicationLifecycleEvents ()Z } +public final class io/customer/datapipelines/config/ScreenView : java/lang/Enum { + public static final field Analytics Lio/customer/datapipelines/config/ScreenView; + public static final field Companion Lio/customer/datapipelines/config/ScreenView$Companion; + public static final field InApp Lio/customer/datapipelines/config/ScreenView; + public static fun valueOf (Ljava/lang/String;)Lio/customer/datapipelines/config/ScreenView; + public static fun values ()[Lio/customer/datapipelines/config/ScreenView; +} + +public final class io/customer/datapipelines/config/ScreenView$Companion { + public final fun getScreenView (Ljava/lang/String;)Lio/customer/datapipelines/config/ScreenView; + public final fun getScreenView (Ljava/lang/String;Lio/customer/datapipelines/config/ScreenView;)Lio/customer/datapipelines/config/ScreenView; + public static synthetic fun getScreenView$default (Lio/customer/datapipelines/config/ScreenView$Companion;Ljava/lang/String;Lio/customer/datapipelines/config/ScreenView;ILjava/lang/Object;)Lio/customer/datapipelines/config/ScreenView; +} + public final class io/customer/datapipelines/extensions/JsonExtensionsKt { public static final fun toJsonArray (Lorg/json/JSONArray;)Lkotlinx/serialization/json/JsonArray; public static final fun toJsonObject (Lorg/json/JSONObject;)Lkotlinx/serialization/json/JsonObject; @@ -136,6 +151,24 @@ public final class io/customer/datapipelines/plugins/PluginExtensionsKt { public static final fun findInContextAtPath (Lcom/segment/analytics/kotlin/core/BaseEvent;Ljava/lang/String;)Ljava/util/List; } +public final class io/customer/datapipelines/plugins/ScreenFilterPlugin : com/segment/analytics/kotlin/core/platform/EventPlugin { + public field analytics Lcom/segment/analytics/kotlin/core/Analytics; + public fun (Lio/customer/datapipelines/config/ScreenView;)V + public fun alias (Lcom/segment/analytics/kotlin/core/AliasEvent;)Lcom/segment/analytics/kotlin/core/BaseEvent; + public fun execute (Lcom/segment/analytics/kotlin/core/BaseEvent;)Lcom/segment/analytics/kotlin/core/BaseEvent; + public fun flush ()V + public fun getAnalytics ()Lcom/segment/analytics/kotlin/core/Analytics; + public fun getType ()Lcom/segment/analytics/kotlin/core/platform/Plugin$Type; + public fun group (Lcom/segment/analytics/kotlin/core/GroupEvent;)Lcom/segment/analytics/kotlin/core/BaseEvent; + public fun identify (Lcom/segment/analytics/kotlin/core/IdentifyEvent;)Lcom/segment/analytics/kotlin/core/BaseEvent; + public fun reset ()V + public fun screen (Lcom/segment/analytics/kotlin/core/ScreenEvent;)Lcom/segment/analytics/kotlin/core/BaseEvent; + public fun setAnalytics (Lcom/segment/analytics/kotlin/core/Analytics;)V + public fun setup (Lcom/segment/analytics/kotlin/core/Analytics;)V + public fun track (Lcom/segment/analytics/kotlin/core/TrackEvent;)Lcom/segment/analytics/kotlin/core/BaseEvent; + public fun update (Lcom/segment/analytics/kotlin/core/Settings;Lcom/segment/analytics/kotlin/core/platform/Plugin$UpdateType;)V +} + public final class io/customer/datapipelines/plugins/StringExtensionsKt { public static final fun getScreenNameFromActivity (Ljava/lang/String;)Ljava/lang/String; } @@ -183,6 +216,7 @@ public final class io/customer/sdk/CustomerIOBuilder { public final fun logLevel (Lio/customer/sdk/core/util/CioLogLevel;)Lio/customer/sdk/CustomerIOBuilder; public final fun migrationSiteId (Ljava/lang/String;)Lio/customer/sdk/CustomerIOBuilder; public final fun region (Lio/customer/sdk/data/model/Region;)Lio/customer/sdk/CustomerIOBuilder; + public final fun screenViewUse (Lio/customer/datapipelines/config/ScreenView;)Lio/customer/sdk/CustomerIOBuilder; public final fun trackApplicationLifecycleEvents (Z)Lio/customer/sdk/CustomerIOBuilder; } diff --git a/datapipelines/src/main/kotlin/io/customer/datapipelines/config/DataPipelinesModuleConfig.kt b/datapipelines/src/main/kotlin/io/customer/datapipelines/config/DataPipelinesModuleConfig.kt index f9656626b..b9d8f229c 100644 --- a/datapipelines/src/main/kotlin/io/customer/datapipelines/config/DataPipelinesModuleConfig.kt +++ b/datapipelines/src/main/kotlin/io/customer/datapipelines/config/DataPipelinesModuleConfig.kt @@ -27,7 +27,9 @@ class DataPipelinesModuleConfig( // Track screen views for Activities val autoTrackActivityScreens: Boolean, // Configuration options required for migration from earlier versions - val migrationSiteId: String? = null + val migrationSiteId: String? = null, + // Determines how SDK should handle screen view events + val screenViewUse: ScreenView ) : CustomerIOModuleConfig { val apiHost: String = apiHostOverride ?: region.apiHost() val cdnHost: String = cdnHostOverride ?: region.cdnHost() diff --git a/datapipelines/src/main/kotlin/io/customer/datapipelines/config/ScreenView.kt b/datapipelines/src/main/kotlin/io/customer/datapipelines/config/ScreenView.kt new file mode 100644 index 000000000..d76e382f4 --- /dev/null +++ b/datapipelines/src/main/kotlin/io/customer/datapipelines/config/ScreenView.kt @@ -0,0 +1,28 @@ +package io.customer.datapipelines.config + +/** + * Enum class to define how CustomerIO SDK should handle screen view events. + */ +enum class ScreenView { + /** + * Screen view events are sent to our back end servers for analytics purposes. + */ + Analytics, + + /** + * Screen view events are kept on device only. They are used to display in-app messages based on page rules. Events are not sent to our back end servers. + */ + InApp; + + companion object { + /** + * Returns the [ScreenView] enum constant for the given name. + * Returns fallback if the specified enum type has no constant with the given name. + * Defaults to [Analytics]. + */ + @JvmOverloads + fun getScreenView(screenView: String?, fallback: ScreenView = Analytics): ScreenView { + return values().firstOrNull { it.name.equals(screenView, ignoreCase = true) } ?: fallback + } + } +} diff --git a/datapipelines/src/main/kotlin/io/customer/datapipelines/plugins/ScreenFilterPlugin.kt b/datapipelines/src/main/kotlin/io/customer/datapipelines/plugins/ScreenFilterPlugin.kt new file mode 100644 index 000000000..82101bb85 --- /dev/null +++ b/datapipelines/src/main/kotlin/io/customer/datapipelines/plugins/ScreenFilterPlugin.kt @@ -0,0 +1,27 @@ +package io.customer.datapipelines.plugins + +import com.segment.analytics.kotlin.core.Analytics +import com.segment.analytics.kotlin.core.BaseEvent +import com.segment.analytics.kotlin.core.ScreenEvent +import com.segment.analytics.kotlin.core.platform.EventPlugin +import com.segment.analytics.kotlin.core.platform.Plugin +import io.customer.datapipelines.config.ScreenView + +/** + * Plugin to filter screen events based on the configuration provided by customer app. + * This plugin is used to filter out screen events that should not be processed further. + */ +class ScreenFilterPlugin(private val screenViewUse: ScreenView) : EventPlugin { + override lateinit var analytics: Analytics + override val type: Plugin.Type = Plugin.Type.Enrichment + + override fun screen(payload: ScreenEvent): BaseEvent? { + // Filter out screen events based on the configuration provided by customer app + // Using when expression so it enforce right check for all possible values of ScreenView in future + return when (screenViewUse) { + ScreenView.Analytics -> payload + // Do not send screen events to server if ScreenView is not Analytics + ScreenView.InApp -> null + } + } +} diff --git a/datapipelines/src/main/kotlin/io/customer/sdk/CustomerIO.kt b/datapipelines/src/main/kotlin/io/customer/sdk/CustomerIO.kt index 5d4dd2450..3577d83f1 100644 --- a/datapipelines/src/main/kotlin/io/customer/sdk/CustomerIO.kt +++ b/datapipelines/src/main/kotlin/io/customer/sdk/CustomerIO.kt @@ -21,6 +21,7 @@ import io.customer.datapipelines.plugins.AutomaticActivityScreenTrackingPlugin import io.customer.datapipelines.plugins.ContextPlugin import io.customer.datapipelines.plugins.CustomerIODestination import io.customer.datapipelines.plugins.DataPipelinePublishedEvents +import io.customer.datapipelines.plugins.ScreenFilterPlugin import io.customer.datapipelines.util.EventNames import io.customer.sdk.communication.Event import io.customer.sdk.communication.subscribe @@ -121,6 +122,9 @@ class CustomerIO private constructor( // Add plugin to publish events to EventBus for other modules to consume analytics.add(DataPipelinePublishedEvents()) + // Add plugin to filter events based on SDK configuration + analytics.add(ScreenFilterPlugin(moduleConfig.screenViewUse)) + // subscribe to journey events emitted from push/in-app module to send them via data pipelines subscribeToJourneyEvents() // if profile is already identified, republish identifier for late-added modules. diff --git a/datapipelines/src/main/kotlin/io/customer/sdk/CustomerIOBuilder.kt b/datapipelines/src/main/kotlin/io/customer/sdk/CustomerIOBuilder.kt index e8a3ee86e..78544b471 100644 --- a/datapipelines/src/main/kotlin/io/customer/sdk/CustomerIOBuilder.kt +++ b/datapipelines/src/main/kotlin/io/customer/sdk/CustomerIOBuilder.kt @@ -3,6 +3,7 @@ package io.customer.sdk import android.app.Application import com.segment.analytics.kotlin.core.platform.policies.FlushPolicy import io.customer.datapipelines.config.DataPipelinesModuleConfig +import io.customer.datapipelines.config.ScreenView import io.customer.sdk.core.di.SDKComponent import io.customer.sdk.core.di.setupAndroidComponent import io.customer.sdk.core.module.CustomerIOModule @@ -69,6 +70,9 @@ class CustomerIOBuilder( // Configuration options required for migration from earlier versions private var migrationSiteId: String? = null + // Determines how SDK should handle screen view events + private var screenViewUse: ScreenView = ScreenView.Analytics + /** * Specifies the log level for the SDK. * Default value is [CioLogLevel.ERROR]. @@ -167,6 +171,16 @@ class CustomerIOBuilder( return this } + /** + * Set the screen view configuration for the SDK. + * + * @see ScreenView for more details. + */ + fun screenViewUse(screenView: ScreenView): CustomerIOBuilder { + this.screenViewUse = screenView + return this + } + fun addCustomerIOModule(module: CustomerIOModule): CustomerIOBuilder { registeredModules.add(module) return this @@ -191,7 +205,8 @@ class CustomerIOBuilder( trackApplicationLifecycleEvents = trackApplicationLifecycleEvents, autoTrackDeviceAttributes = autoTrackDeviceAttributes, autoTrackActivityScreens = autoTrackActivityScreens, - migrationSiteId = migrationSiteId + migrationSiteId = migrationSiteId, + screenViewUse = screenViewUse ) // Initialize CustomerIO instance before initializing the modules diff --git a/datapipelines/src/test/java/io/customer/datapipelines/plugins/ScreenFilterPluginTest.kt b/datapipelines/src/test/java/io/customer/datapipelines/plugins/ScreenFilterPluginTest.kt new file mode 100644 index 000000000..f3cce11e5 --- /dev/null +++ b/datapipelines/src/test/java/io/customer/datapipelines/plugins/ScreenFilterPluginTest.kt @@ -0,0 +1,72 @@ +package io.customer.datapipelines.plugins + +import io.customer.commontest.config.TestConfig +import io.customer.commontest.extensions.random +import io.customer.datapipelines.config.ScreenView +import io.customer.datapipelines.testutils.core.DataPipelinesTestConfig +import io.customer.datapipelines.testutils.core.JUnitTest +import io.customer.datapipelines.testutils.core.testConfiguration +import io.customer.datapipelines.testutils.extensions.shouldMatchTo +import io.customer.datapipelines.testutils.utils.OutputReaderPlugin +import io.customer.datapipelines.testutils.utils.screenEvents +import io.customer.sdk.data.model.CustomAttributes +import org.amshove.kluent.shouldBeEmpty +import org.amshove.kluent.shouldBeEqualTo +import org.amshove.kluent.shouldHaveSingleItem +import org.junit.jupiter.api.Test + +class ScreenFilterPluginTest : JUnitTest() { + private lateinit var outputReaderPlugin: OutputReaderPlugin + + override fun setup(testConfig: TestConfig) { + // Keep setup empty to avoid calling super.setup() as it will initialize the SDK + // and we want to test the SDK with different configurations in each test + } + + private fun setupWithConfig(screenViewUse: ScreenView, testConfig: DataPipelinesTestConfig = testConfiguration {}) { + super.setup( + testConfiguration { + analytics { add(ScreenFilterPlugin(screenViewUse = screenViewUse)) } + } + testConfig + ) + + outputReaderPlugin = OutputReaderPlugin() + analytics.add(outputReaderPlugin) + } + + @Test + fun process_givenScreenViewUseAnalytics_expectScreenEventWithoutPropertiesProcessed() { + setupWithConfig(screenViewUse = ScreenView.Analytics) + + val givenScreenTitle = String.random + sdkInstance.screen(givenScreenTitle) + + val result = outputReaderPlugin.screenEvents.shouldHaveSingleItem() + result.name shouldBeEqualTo givenScreenTitle + result.properties.shouldBeEmpty() + } + + @Test + fun process_givenScreenViewUseAnalytics_expectScreenEventWithPropertiesProcessed() { + setupWithConfig(screenViewUse = ScreenView.Analytics) + + val givenScreenTitle = String.random + val givenProperties: CustomAttributes = mapOf("source" to "push", "discount" to 10) + sdkInstance.screen(givenScreenTitle, givenProperties) + + val screenEvent = outputReaderPlugin.screenEvents.shouldHaveSingleItem() + screenEvent.name shouldBeEqualTo givenScreenTitle + screenEvent.properties shouldMatchTo givenProperties + } + + @Test + fun process_givenScreenViewUseInApp_expectAllScreenEventsIgnored() { + setupWithConfig(screenViewUse = ScreenView.InApp) + + for (i in 1..5) { + sdkInstance.screen(String.random) + } + + outputReaderPlugin.allEvents.shouldBeEmpty() + } +} diff --git a/datapipelines/src/test/java/io/customer/datapipelines/sdk/CustomerIOBuilderTest.kt b/datapipelines/src/test/java/io/customer/datapipelines/sdk/CustomerIOBuilderTest.kt index eb2424160..209955898 100644 --- a/datapipelines/src/test/java/io/customer/datapipelines/sdk/CustomerIOBuilderTest.kt +++ b/datapipelines/src/test/java/io/customer/datapipelines/sdk/CustomerIOBuilderTest.kt @@ -5,9 +5,11 @@ import io.customer.commontest.extensions.assertCalledNever import io.customer.commontest.extensions.assertCalledOnce import io.customer.commontest.extensions.random import io.customer.commontest.module.CustomerIOGenericModule +import io.customer.datapipelines.config.ScreenView import io.customer.datapipelines.plugins.AutomaticActivityScreenTrackingPlugin import io.customer.datapipelines.plugins.CustomerIODestination import io.customer.datapipelines.plugins.DataPipelinePublishedEvents +import io.customer.datapipelines.plugins.ScreenFilterPlugin import io.customer.sdk.CustomerIO import io.customer.sdk.CustomerIOBuilder import io.customer.sdk.core.di.SDKComponent @@ -105,6 +107,7 @@ class CustomerIOBuilderTest : RobolectricTest() { dataPipelinesModuleConfig.apiHost shouldBe "cdp.customer.io/v1" dataPipelinesModuleConfig.cdnHost shouldBe "cdp.customer.io/v1" dataPipelinesModuleConfig.autoAddCustomerIODestination shouldBe true + dataPipelinesModuleConfig.screenViewUse shouldBe ScreenView.Analytics } @Test @@ -112,6 +115,7 @@ class CustomerIOBuilderTest : RobolectricTest() { val givenCdpApiKey = String.random val givenMigrationSiteId = String.random val givenRegion = Region.EU + val givenScreenViewUse = ScreenView.InApp createCustomerIOBuilder(givenCdpApiKey) .logLevel(CioLogLevel.DEBUG) @@ -123,6 +127,7 @@ class CustomerIOBuilderTest : RobolectricTest() { .flushAt(100) .flushInterval(2) .flushPolicies(emptyList()) + .screenViewUse(givenScreenViewUse) .build() // verify the customerIOBuilder config with DataPipelinesModuleConfig @@ -137,6 +142,7 @@ class CustomerIOBuilderTest : RobolectricTest() { dataPipelinesModuleConfig.flushInterval shouldBe 2 dataPipelinesModuleConfig.apiHost shouldBe "cdp-eu.customer.io/v1" dataPipelinesModuleConfig.cdnHost shouldBe "cdp-eu.customer.io/v1" + dataPipelinesModuleConfig.screenViewUse shouldBe givenScreenViewUse // verify the shared logger has updated log level SDKComponent.logger.logLevel shouldBe CioLogLevel.DEBUG @@ -165,6 +171,13 @@ class CustomerIOBuilderTest : RobolectricTest() { CustomerIO.instance().analytics.find(AutomaticActivityScreenTrackingPlugin::class) shouldBe null } + @Test + fun build_givenModuleInitialized_expectScreenFilterPluginPluginAdded() { + createCustomerIOBuilder().build() + + CustomerIO.instance().analytics.find(ScreenFilterPlugin::class) shouldNotBe null + } + @Test fun build_givenHostConfiguration_expectCorrectHostDataPipelinesModuleConfig() { val givenRegion = Region.EU From a55ecbbd5c783e8847cd059af169e047c478a1c2 Mon Sep 17 00:00:00 2001 From: Muhammad Rehan Date: Mon, 16 Dec 2024 15:10:50 +0500 Subject: [PATCH 2/5] chore: update java sample app with screen view configuration (#475) --- .../data/model/CustomerIOSDKConfig.java | 14 ++++++ .../java_layout/sdk/CustomerIORepository.java | 1 + .../ui/settings/InternalSettingsActivity.java | 1 + .../ui/settings/SettingsActivity.java | 26 +++++++++++ .../src/main/res/layout/activity_settings.xml | 43 ++++++++++++++++++- .../src/main/res/values/strings.xml | 3 ++ 6 files changed, 87 insertions(+), 1 deletion(-) diff --git a/samples/java_layout/src/main/java/io/customer/android/sample/java_layout/data/model/CustomerIOSDKConfig.java b/samples/java_layout/src/main/java/io/customer/android/sample/java_layout/data/model/CustomerIOSDKConfig.java index f53da4f00..3a4df8716 100644 --- a/samples/java_layout/src/main/java/io/customer/android/sample/java_layout/data/model/CustomerIOSDKConfig.java +++ b/samples/java_layout/src/main/java/io/customer/android/sample/java_layout/data/model/CustomerIOSDKConfig.java @@ -11,6 +11,7 @@ import io.customer.android.sample.java_layout.BuildConfig; import io.customer.android.sample.java_layout.support.Optional; import io.customer.android.sample.java_layout.utils.StringUtils; +import io.customer.datapipelines.config.ScreenView; import io.customer.datapipelines.extensions.RegionExtKt; import io.customer.sdk.core.util.CioLogLevel; import io.customer.sdk.data.model.Region; @@ -28,6 +29,7 @@ private static class Keys { static final String TRACK_DEVICE_ATTRIBUTES = "cio_sdk_track_device_attributes"; static final String LOG_LEVEL = "cio_sdk_log_level"; static final String REGION = "cio_sdk_region"; + static final String SCREEN_VIEW_USE = "cio_sdk_screen_view_use"; static final String TRACK_APPLICATION_LIFECYCLE = "cio_sdk_track_application_lifecycle"; static final String TEST_MODE_ENABLED = "cio_sdk_test_mode"; static final String IN_APP_MESSAGING_ENABLED = "cio_sdk_in_app_messaging_enabled"; @@ -42,6 +44,7 @@ public static CustomerIOSDKConfig getDefaultConfigurations() { true, CioLogLevel.DEBUG, Region.US.INSTANCE, + ScreenView.Analytics, true, false, true); @@ -62,6 +65,7 @@ public static Optional fromMap(@NonNull Map boolean deviceAttributesTrackingEnabled = StringUtils.parseBoolean(bundle.get(Keys.TRACK_DEVICE_ATTRIBUTES), defaultConfig.deviceAttributesTrackingEnabled); CioLogLevel logLevel = CioLogLevel.Companion.getLogLevel(bundle.get(Keys.LOG_LEVEL), CioLogLevel.DEBUG); Region region = Region.Companion.getRegion(bundle.get(Keys.REGION), Region.US.INSTANCE); + ScreenView screenViewUse = ScreenView.Companion.getScreenView(bundle.get(Keys.SCREEN_VIEW_USE)); boolean applicationLifecycleTrackingEnabled = StringUtils.parseBoolean(bundle.get(Keys.TRACK_APPLICATION_LIFECYCLE), defaultConfig.applicationLifecycleTrackingEnabled); boolean testModeEnabled = StringUtils.parseBoolean(bundle.get(Keys.TEST_MODE_ENABLED), defaultConfig.testModeEnabled); boolean inAppMessagingEnabled = StringUtils.parseBoolean(bundle.get(Keys.IN_APP_MESSAGING_ENABLED), defaultConfig.inAppMessagingEnabled); @@ -74,6 +78,7 @@ public static Optional fromMap(@NonNull Map deviceAttributesTrackingEnabled, logLevel, region, + screenViewUse, applicationLifecycleTrackingEnabled, testModeEnabled, inAppMessagingEnabled); @@ -91,6 +96,7 @@ public static Map toMap(@NonNull CustomerIOSDKConfig config) { bundle.put(Keys.TRACK_DEVICE_ATTRIBUTES, StringUtils.fromBoolean(config.deviceAttributesTrackingEnabled)); bundle.put(Keys.LOG_LEVEL, config.logLevel.name()); bundle.put(Keys.REGION, config.getRegion().getCode()); + bundle.put(Keys.SCREEN_VIEW_USE, config.getScreenViewUse().name()); bundle.put(Keys.TRACK_APPLICATION_LIFECYCLE, StringUtils.fromBoolean(config.applicationLifecycleTrackingEnabled)); bundle.put(Keys.TEST_MODE_ENABLED, StringUtils.fromBoolean(config.testModeEnabled)); bundle.put(Keys.IN_APP_MESSAGING_ENABLED, StringUtils.fromBoolean(config.inAppMessagingEnabled)); @@ -111,6 +117,7 @@ public static Map toMap(@NonNull CustomerIOSDKConfig config) { private final CioLogLevel logLevel; @NonNull private final Region region; + private final ScreenView screenViewUse; private final boolean applicationLifecycleTrackingEnabled; private final boolean testModeEnabled; private final boolean inAppMessagingEnabled; @@ -123,6 +130,7 @@ public CustomerIOSDKConfig(@NonNull String cdpApiKey, boolean deviceAttributesTrackingEnabled, @NonNull CioLogLevel logLevel, @NonNull Region region, + @NonNull ScreenView screenViewUse, boolean applicationLifecycleTrackingEnabled, boolean testModeEnabled, boolean inAppMessagingEnabled) { @@ -134,6 +142,7 @@ public CustomerIOSDKConfig(@NonNull String cdpApiKey, this.deviceAttributesTrackingEnabled = deviceAttributesTrackingEnabled; this.logLevel = logLevel; this.region = region; + this.screenViewUse = screenViewUse; this.applicationLifecycleTrackingEnabled = applicationLifecycleTrackingEnabled; this.testModeEnabled = testModeEnabled; this.inAppMessagingEnabled = inAppMessagingEnabled; @@ -188,4 +197,9 @@ public boolean isApplicationLifecycleTrackingEnabled() { public Region getRegion() { return region; } + + @NonNull + public ScreenView getScreenViewUse() { + return screenViewUse; + } } diff --git a/samples/java_layout/src/main/java/io/customer/android/sample/java_layout/sdk/CustomerIORepository.java b/samples/java_layout/src/main/java/io/customer/android/sample/java_layout/sdk/CustomerIORepository.java index 05aa8a9be..47d41e7e9 100644 --- a/samples/java_layout/src/main/java/io/customer/android/sample/java_layout/sdk/CustomerIORepository.java +++ b/samples/java_layout/src/main/java/io/customer/android/sample/java_layout/sdk/CustomerIORepository.java @@ -77,6 +77,7 @@ private void configureSdk(CustomerIOBuilder builder, final CustomerIOSDKConfig s builder.trackApplicationLifecycleEvents(sdkConfig.isApplicationLifecycleTrackingEnabled()); builder.region(sdkConfig.getRegion()); builder.logLevel(sdkConfig.getLogLevel()); + builder.screenViewUse(sdkConfig.getScreenViewUse()); } public void identify(@NonNull String email, @NonNull Map attributes) { diff --git a/samples/java_layout/src/main/java/io/customer/android/sample/java_layout/ui/settings/InternalSettingsActivity.java b/samples/java_layout/src/main/java/io/customer/android/sample/java_layout/ui/settings/InternalSettingsActivity.java index f53260ff4..7cd5c5195 100644 --- a/samples/java_layout/src/main/java/io/customer/android/sample/java_layout/ui/settings/InternalSettingsActivity.java +++ b/samples/java_layout/src/main/java/io/customer/android/sample/java_layout/ui/settings/InternalSettingsActivity.java @@ -137,6 +137,7 @@ private static CustomerIOSDKConfig createNewSettings(CustomerIOSDKConfig current currentSettings.isDeviceAttributesTrackingEnabled(), currentSettings.getLogLevel(), currentSettings.getRegion(), + currentSettings.getScreenViewUse(), currentSettings.isApplicationLifecycleTrackingEnabled(), currentSettings.isTestModeEnabled(), currentSettings.isInAppMessagingEnabled() diff --git a/samples/java_layout/src/main/java/io/customer/android/sample/java_layout/ui/settings/SettingsActivity.java b/samples/java_layout/src/main/java/io/customer/android/sample/java_layout/ui/settings/SettingsActivity.java index aa237c585..ce11ec4fd 100644 --- a/samples/java_layout/src/main/java/io/customer/android/sample/java_layout/ui/settings/SettingsActivity.java +++ b/samples/java_layout/src/main/java/io/customer/android/sample/java_layout/ui/settings/SettingsActivity.java @@ -17,6 +17,7 @@ import io.customer.android.sample.java_layout.ui.dashboard.DashboardActivity; import io.customer.android.sample.java_layout.utils.OSUtils; import io.customer.android.sample.java_layout.utils.ViewUtils; +import io.customer.datapipelines.config.ScreenView; import io.customer.sdk.core.util.CioLogLevel; import io.customer.sdk.data.model.Region; import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; @@ -128,6 +129,7 @@ private void updateIOWithConfig(@NonNull CustomerIOSDKConfig config) { binding.settingsTrackDeviceAttrsValuesGroup.check(getCheckedAutoTrackDeviceAttributesButtonId(config.isDeviceAttributesTrackingEnabled())); binding.settingsTrackScreenViewsValuesGroup.check(getCheckedTrackScreenViewsButtonId(config.isScreenTrackingEnabled())); binding.settingsTrackAppLifecycleValuesGroup.check(getCheckedTrackAppLifecycleButtonId(config.isApplicationLifecycleTrackingEnabled())); + binding.screenViewUseSettingsValuesGroup.check(getCheckedScreenViewUseButtonId(config.getScreenViewUse())); binding.settingsLogLevelValuesGroup.check(getCheckedLogLevelButtonId(config.getLogLevel())); binding.settingsTestModeValuesGroup.check(getCheckedTestModeButtonId(config.isTestModeEnabled())); binding.settingsInAppMessagingValuesGroup.check(getCheckedInAppMessagingButtonId(config.isInAppMessagingEnabled())); @@ -173,6 +175,7 @@ private CustomerIOSDKConfig createNewSettings(String cdpApiKey, String siteId, C boolean featInAppMessagingEnabled = binding.settingsInAppMessagingValuesGroup.getCheckedButtonId() == R.id.settings_in_app_messaging_yes_button; CioLogLevel logLevel = getSelectedLogLevel(); Region region = getSelectedRegion(); + ScreenView screenViewUse = getSelectedScreenViewUse(); return new CustomerIOSDKConfig(cdpApiKey, siteId, @@ -182,6 +185,7 @@ private CustomerIOSDKConfig createNewSettings(String cdpApiKey, String siteId, C featTrackDeviceAttributes, logLevel, region, + screenViewUse, featTrackApplicationLifecycle, featTestModeEnabled, featInAppMessagingEnabled); @@ -213,6 +217,18 @@ private Region getSelectedRegion() { throw new IllegalStateException(); } + + @NonNull + private ScreenView getSelectedScreenViewUse() { + int checkedButton = binding.screenViewUseSettingsValuesGroup.getCheckedButtonId(); + if (checkedButton == R.id.settings_screen_view_use_analytics_button) { + return ScreenView.Analytics; + } else if (checkedButton == R.id.settings_screen_view_use_in_app_button) { + return ScreenView.InApp; + } + throw new IllegalStateException(); + } + private int getCheckedInAppMessagingButtonId(boolean enabled) { return enabled ? R.id.settings_in_app_messaging_yes_button : R.id.settings_in_app_messaging_no_button; } @@ -256,6 +272,16 @@ private int getCheckedRegionButtonId(@NonNull Region region) { : R.id.settings_region_eu_button; } + private int getCheckedScreenViewUseButtonId(@NonNull ScreenView screenViewUse) { + switch (screenViewUse) { + case InApp: + return R.id.settings_screen_view_use_in_app_button; + case Analytics: + default: + return R.id.settings_screen_view_use_analytics_button; + } + } + private boolean updateErrorState(TextInputLayout textInputLayout, boolean isErrorEnabled, @StringRes int errorResId) { diff --git a/samples/java_layout/src/main/res/layout/activity_settings.xml b/samples/java_layout/src/main/res/layout/activity_settings.xml index f448e50da..811933619 100644 --- a/samples/java_layout/src/main/res/layout/activity_settings.xml +++ b/samples/java_layout/src/main/res/layout/activity_settings.xml @@ -234,6 +234,47 @@ android:text="@string/settings_no" /> + + + + +