Skip to content

Commit

Permalink
feat(all): Add Gen2 Config (#2771)
Browse files Browse the repository at this point in the history
  • Loading branch information
mattcreaser committed Apr 26, 2024
1 parent b90e443 commit 1d50ae8
Show file tree
Hide file tree
Showing 64 changed files with 3,631 additions and 200 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ __pycache__/
**/credentials.json
**/google_client_creds.json
**/amplifyconfiguration*.json
**/amplify_outputs.json

# IDE files
.idea/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* Copyright 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/

package com.amplifyframework.annotations

/**
* APIs marked with this annotation are visible for usage from the Amplify Flutter library, and are not intended
* for external use. They may change or be removed without warning.
*
* We strongly recommend to not use such API.
*/
@RequiresOptIn(
level = RequiresOptIn.Level.ERROR,
message = "This API is for Amplify Flutter and should not be used elsewhere. " +
"It could be removed or changed without notice."
)
@Target(
AnnotationTarget.CLASS,
AnnotationTarget.TYPEALIAS,
AnnotationTarget.FUNCTION,
AnnotationTarget.PROPERTY,
AnnotationTarget.FIELD,
AnnotationTarget.CONSTRUCTOR
)
annotation class AmplifyFlutterApi
30 changes: 30 additions & 0 deletions aws-analytics-pinpoint/api/aws-analytics-pinpoint.api
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
public final class com/amplifyframework/analytics/pinpoint/AWSPinpointAnalyticsPlugin : com/amplifyframework/analytics/AnalyticsPlugin {
public fun <init> ()V
public fun <init> (Lcom/amplifyframework/analytics/pinpoint/AWSPinpointAnalyticsPlugin$Options;)V
public synthetic fun <init> (Lcom/amplifyframework/analytics/pinpoint/AWSPinpointAnalyticsPlugin$Options;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public fun configure (Lorg/json/JSONObject;Landroid/content/Context;)V
public fun disable ()V
public fun enable ()V
Expand All @@ -15,6 +17,34 @@ public final class com/amplifyframework/analytics/pinpoint/AWSPinpointAnalyticsP
public fun unregisterGlobalProperties ([Ljava/lang/String;)V
}

public final class com/amplifyframework/analytics/pinpoint/AWSPinpointAnalyticsPlugin$Options {
public static final field Companion Lcom/amplifyframework/analytics/pinpoint/AWSPinpointAnalyticsPlugin$Options$Companion;
public static final fun builder ()Lcom/amplifyframework/analytics/pinpoint/AWSPinpointAnalyticsPlugin$Options$Builder;
public final fun component1 ()J
public final fun component2 ()Z
public final fun copy (JZ)Lcom/amplifyframework/analytics/pinpoint/AWSPinpointAnalyticsPlugin$Options;
public static synthetic fun copy$default (Lcom/amplifyframework/analytics/pinpoint/AWSPinpointAnalyticsPlugin$Options;JZILjava/lang/Object;)Lcom/amplifyframework/analytics/pinpoint/AWSPinpointAnalyticsPlugin$Options;
public fun equals (Ljava/lang/Object;)Z
public final fun getAutoFlushEventsInterval ()J
public final fun getTrackLifecycleEvents ()Z
public fun hashCode ()I
public fun toString ()Ljava/lang/String;
}

public final class com/amplifyframework/analytics/pinpoint/AWSPinpointAnalyticsPlugin$Options$Builder {
public final fun autoFlushEventsInterval (J)Lcom/amplifyframework/analytics/pinpoint/AWSPinpointAnalyticsPlugin$Options$Builder;
public final fun getAutoFlushEventsInterval ()J
public final fun getTrackLifecycleEvents ()Z
public final synthetic fun setAutoFlushEventsInterval (J)V
public final synthetic fun setTrackLifecycleEvents (Z)V
public final fun trackLifecycleEvents (Z)Lcom/amplifyframework/analytics/pinpoint/AWSPinpointAnalyticsPlugin$Options$Builder;
}

public final class com/amplifyframework/analytics/pinpoint/AWSPinpointAnalyticsPlugin$Options$Companion {
public final fun builder ()Lcom/amplifyframework/analytics/pinpoint/AWSPinpointAnalyticsPlugin$Options$Builder;
public final synthetic fun invoke (Lkotlin/jvm/functions/Function1;)Lcom/amplifyframework/analytics/pinpoint/AWSPinpointAnalyticsPlugin$Options;
}

public final class com/amplifyframework/analytics/pinpoint/AnalyticsChannelEventName : java/lang/Enum {
public static final field FLUSH_EVENTS Lcom/amplifyframework/analytics/pinpoint/AnalyticsChannelEventName;
public static fun getEntries ()Lkotlin/enums/EnumEntries;
Expand Down
2 changes: 2 additions & 0 deletions aws-analytics-pinpoint/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ dependencies {
testImplementation(libs.test.androidx.junit)
testImplementation(libs.test.androidx.core)
testImplementation(libs.test.kotlin.coroutines)
testImplementation(libs.test.kotest.assertions)
testImplementation(project(":testutils"))
testImplementation(project(":aws-analytics-pinpoint"))

androidTestImplementation(project(":testutils"))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,17 @@ import com.amplifyframework.analytics.AnalyticsEventBehavior
import com.amplifyframework.analytics.AnalyticsPlugin
import com.amplifyframework.analytics.AnalyticsProperties
import com.amplifyframework.analytics.UserProfile
import com.amplifyframework.annotations.InternalAmplifyApi
import com.amplifyframework.auth.CognitoCredentialsProvider
import com.amplifyframework.core.configuration.AmplifyOutputsData
import org.json.JSONObject

/**
* The plugin implementation for Amazon Pinpoint in Analytics category.
*/
class AWSPinpointAnalyticsPlugin : AnalyticsPlugin<PinpointClient>() {
class AWSPinpointAnalyticsPlugin @JvmOverloads constructor(
private val userOptions: Options? = null
) : AnalyticsPlugin<PinpointClient>() {

private val pluginKey = "awsPinpointAnalyticsPlugin"
private val analyticsConfigKey = "pinpointAnalytics"
Expand Down Expand Up @@ -79,28 +83,47 @@ class AWSPinpointAnalyticsPlugin : AnalyticsPlugin<PinpointClient>() {
configBuilder.withRegion(
pinpointAnalyticsConfigJson.getString(PinpointConfigurationKey.REGION.configurationKey)
)
if (pinpointAnalyticsConfigJson.has(PinpointConfigurationKey.AUTO_FLUSH_INTERVAL.configurationKey)) {
configBuilder.withAutoFlushEventsInterval(
pinpointAnalyticsConfigJson.getLong(PinpointConfigurationKey.AUTO_FLUSH_INTERVAL.configurationKey)
)
}
if (pinpointAnalyticsConfigJson.has(PinpointConfigurationKey.TRACK_APP_LIFECYCLE_EVENTS.configurationKey)) {
configBuilder.withTrackAppLifecycleEvents(
pinpointAnalyticsConfigJson.getBoolean(
PinpointConfigurationKey.TRACK_APP_LIFECYCLE_EVENTS.configurationKey

// Use the programmatic options if they were supplied, otherwise read additional options from the
// amplifyconfiguration file
if (userOptions != null) {
configBuilder.withAutoFlushEventsInterval(userOptions.autoFlushEventsInterval)
.withTrackAppLifecycleEvents(userOptions.trackLifecycleEvents)
} else {
if (pinpointAnalyticsConfigJson.has(PinpointConfigurationKey.AUTO_FLUSH_INTERVAL.configurationKey)) {
configBuilder.withAutoFlushEventsInterval(
pinpointAnalyticsConfigJson.getLong(PinpointConfigurationKey.AUTO_FLUSH_INTERVAL.configurationKey)
)
)
}
if (pinpointAnalyticsConfigJson.has(PinpointConfigurationKey.TRACK_APP_LIFECYCLE_EVENTS.configurationKey)) {
configBuilder.withTrackAppLifecycleEvents(
pinpointAnalyticsConfigJson.getBoolean(
PinpointConfigurationKey.TRACK_APP_LIFECYCLE_EVENTS.configurationKey
)
)
}
}
val awsAnalyticsConfig = configBuilder.build()
configure(awsAnalyticsConfig, context)
}

@InternalAmplifyApi
override fun configure(configuration: AmplifyOutputsData, context: Context) {
val options = this.userOptions ?: Options.defaults()
val analyticsConfig = AWSPinpointAnalyticsPluginConfiguration.from(configuration, options)
configure(analyticsConfig, context)
}

private fun configure(configuration: AWSPinpointAnalyticsPluginConfiguration, context: Context) {
pinpointManager = PinpointManager(
context,
awsAnalyticsConfig,
configuration,
CognitoCredentialsProvider()
)

awsPinpointAnalyticsPluginBehavior = AWSPinpointAnalyticsPluginBehavior(
pinpointManager.analyticsClient,
pinpointManager.targetingClient,
pinpointManager.targetingClient
)
}

Expand All @@ -111,6 +134,69 @@ class AWSPinpointAnalyticsPlugin : AnalyticsPlugin<PinpointClient>() {
override fun getVersion(): String {
return BuildConfig.VERSION_NAME
}

/**
* Options that can be specified to fine-tune the behavior of the Pinpoint Analytics Plugin.
*/
data class Options internal constructor(
/**
* The interval between sends of queued analytics events, in milliseconds
*/
val autoFlushEventsInterval: Long,

/**
* If true then the plugin will stop sessions when the app goes to the background
*/
val trackLifecycleEvents: Boolean
) {
companion object {
/**
* Create a new [Builder] instance
*/
@JvmStatic
fun builder() = Builder()

/**
* Create an [AWSPinpointAnalyticsPlugin.Options] instance
*/
@JvmSynthetic
operator fun invoke(func: Builder.() -> Unit) = Builder().apply(func).build()

internal fun defaults() = builder().build()
}

/**
* Builder API for constructing [AWSPinpointAnalyticsPlugin.Options] instances
*/
class Builder internal constructor() {
/**
* Set the interval between sends of queued analytics events, in milliseconds
*/
var autoFlushEventsInterval: Long = AWSPinpointAnalyticsPluginConfiguration.DEFAULT_AUTO_FLUSH_INTERVAL
@JvmSynthetic set

/**
* Set whether or not the plugin will stop/start sessions when the app goes to the background/foreground.
*/
var trackLifecycleEvents: Boolean = true
@JvmSynthetic set

/**
* Set the interval between sends of queed analytics events, in milliseconds
*/
fun autoFlushEventsInterval(value: Long) = apply { autoFlushEventsInterval = value }

/**
* Set whether or not the plugin will stop/start sessions when the app goes to the background/foreground.
*/
fun trackLifecycleEvents(value: Boolean) = apply { trackLifecycleEvents = value }

internal fun build() = Options(
autoFlushEventsInterval = autoFlushEventsInterval,
trackLifecycleEvents = trackLifecycleEvents
)
}
}
}

private enum class PinpointConfigurationKey(
Expand All @@ -137,5 +223,5 @@ private enum class PinpointConfigurationKey(
/**
* Whether to track app lifecycle events automatically.
*/
TRACK_APP_LIFECYCLE_EVENTS("trackAppLifecycleEvents");
TRACK_APP_LIFECYCLE_EVENTS("trackAppLifecycleEvents")
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,24 +15,31 @@

package com.amplifyframework.analytics.pinpoint;

import androidx.annotation.NonNull;

import com.amplifyframework.AmplifyException;
import com.amplifyframework.analytics.AnalyticsException;
import com.amplifyframework.annotations.InternalAmplifyApi;
import com.amplifyframework.core.configuration.AmplifyOutputsData;

/**
* Configuration options for Amplify Analytics Pinpoint plugin.
*/
final class AWSPinpointAnalyticsPluginConfiguration {

private static final long DEFAULT_AUTO_FLUSH_INTERVAL = 30000L;
static final long DEFAULT_AUTO_FLUSH_INTERVAL = 30000L;

// Pinpoint plugin configuration options
private final String appId;
private final boolean trackAppLifecycleEvents;
private final String region;
private final long autoFlushEventsInterval;
private final boolean trackAppLifecycleEvents;

private AWSPinpointAnalyticsPluginConfiguration(Builder builder) {
this.appId = builder.appId;
this.region = builder.region;
this.trackAppLifecycleEvents = builder.trackAppLifecycleEvents;
this.autoFlushEventsInterval = builder.autoFlushEventsInterval;
this.trackAppLifecycleEvents = builder.trackAppLifecycleEvents;
}

/**
Expand Down Expand Up @@ -73,20 +80,43 @@ boolean isTrackAppLifecycleEvents() {
/**
* Return a builder that can be used to construct a new instance of
* {@link AWSPinpointAnalyticsPluginConfiguration}.
* @return An {@link PinpointProperties.Builder} instance
* @return An {@link AWSPinpointAnalyticsPluginConfiguration.Builder} instance
*/
static Builder builder() {
return new Builder();
}

@InternalAmplifyApi
static AWSPinpointAnalyticsPluginConfiguration from(
@NonNull AmplifyOutputsData outputs,
@NonNull AWSPinpointAnalyticsPlugin.Options options
) throws AmplifyException {
AmplifyOutputsData.Analytics analytics = outputs.getAnalytics();
if (analytics == null || analytics.getAmazonPinpoint() == null) {
throw new AnalyticsException(
"Missing Analytics configuration",
"Ensure that analytics is enabled and exists in your configuration file"
);
}

// Note: autoFlushEventsInterval is not supported in Gen2 config.
// Customers should use the programmatic plugin options API instead.
return builder()
.withAppId(analytics.getAmazonPinpoint().getAppId())
.withRegion(analytics.getAmazonPinpoint().getAwsRegion())
.withAutoFlushEventsInterval(options.getAutoFlushEventsInterval())
.withTrackAppLifecycleEvents(options.getTrackLifecycleEvents())
.build();
}

/**
* Used for fluent construction of an immutable {@link AWSPinpointAnalyticsPluginConfiguration} object.
*/
static final class Builder {
private String appId;
private boolean trackAppLifecycleEvents = false;
private String region;
private long autoFlushEventsInterval = DEFAULT_AUTO_FLUSH_INTERVAL;
private boolean trackAppLifecycleEvents = true;

Builder withAppId(final String appId) {
this.appId = appId;
Expand All @@ -98,13 +128,13 @@ Builder withRegion(final String region) {
return this;
}

Builder withAutoFlushEventsInterval(final long autoFlushEventsInterval) {
this.autoFlushEventsInterval = autoFlushEventsInterval;
Builder withTrackAppLifecycleEvents(final boolean trackAppLifecycleEvents) {
this.trackAppLifecycleEvents = trackAppLifecycleEvents;
return this;
}

Builder withTrackAppLifecycleEvents(final boolean trackAppLifecycleEvents) {
this.trackAppLifecycleEvents = trackAppLifecycleEvents;
Builder withAutoFlushEventsInterval(final long autoFlushEventsInterval) {
this.autoFlushEventsInterval = autoFlushEventsInterval;
return this;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,17 +75,18 @@ internal class PinpointManager constructor(
encryptedStore,
sharedPrefs,
androidAppDetails,
androidDeviceDetails,
androidDeviceDetails
)
analyticsClient = AnalyticsClient(
context,
awsPinpointConfiguration.autoFlushEventsInterval,
awsPinpointConfiguration.isTrackAppLifecycleEvents,
pinpointClient,
targetingClient,
pinpointDatabase,
sharedPrefs.getUniqueId(),
androidAppDetails,
androidDeviceDetails,
androidDeviceDetails
)
}
}
Loading

0 comments on commit 1d50ae8

Please sign in to comment.