From ebaaa32fac372f68e5e3b2d666f7be73a2e76158 Mon Sep 17 00:00:00 2001
From: PoornimaApptentive
<85186738+PoornimaApptentive@users.noreply.github.com>
Date: Thu, 6 Jan 2022 11:34:20 -0800
Subject: [PATCH] Apptentive Android SDK 5.8.0 (#234)
---
.github/CODEOWNERS | 2 +-
.idea/runConfigurations.xml | 12 --
CHANGELOG.md | 19 ++-
CONTRIBUTING.md | 2 +-
License.txt | 2 +-
README.md | 4 +-
apptentive/build.gradle | 44 +++----
.../android/sdk/ApptentiveBaseActivity.java | 2 +-
.../android/sdk/ApptentiveConfiguration.java | 21 ++++
.../android/sdk/ApptentiveInstance.java | 3 +
.../android/sdk/ApptentiveInternal.java | 33 ++++--
.../android/sdk/ApptentiveNullInstance.java | 7 ++
.../sdk/conversation/Conversation.java | 12 +-
.../module/engagement/EngagementModule.java | 7 +-
.../fragment/AppStoreRatingFragment.java | 2 +-
.../fragment/ApptentiveBaseFragment.java | 5 +-
.../fragment/MessageCenterFragment.java | 4 +-
.../fragment/NavigateToLinkFragment.java | 2 +-
.../sdk/storage/EncryptedFileSerializer.java | 8 +-
.../android/sdk/util/Constants.java | 2 +-
.../android/sdk/util/ThrottleUtils.java | 47 ++++++++
build.gradle | 52 +++++++-
samples/apptentive-example/build.gradle | 27 ++---
settings.gradle | 4 +-
tests/test-app/build.gradle | 8 +-
.../sdk/tests/misc/ThrottleUtilsTest.java | 111 ++++++++++++++++++
.../module/engagement/InteractionTest.java | 23 ++--
27 files changed, 357 insertions(+), 108 deletions(-)
delete mode 100644 .idea/runConfigurations.xml
create mode 100644 apptentive/src/main/java/com/apptentive/android/sdk/util/ThrottleUtils.java
create mode 100644 tests/test-app/src/androidTest/java/com/apptentive/android/sdk/tests/misc/ThrottleUtilsTest.java
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index fb970f2bd..bb234bca5 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -1 +1 @@
-* @frankus @twinklesharma1311
+* @twinklesharma1311 @ChaseApptentive @PoornimaApptentive
diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml
deleted file mode 100644
index 7f68460d8..000000000
--- a/.idea/runConfigurations.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5cedd12f4..56de09da2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,9 +1,24 @@
+# 2022-01-06 - v5.8.0
+
+#### Major changes
+
+* Add safeguard parameter for interaction frequency of Rating Dialog.
+
+#### Fixes
+
+* Fix a couple of possible ANR issues.
+
+#### Improvements
+
+* Update License & README files.
+
# 2021-08-26 - v5.7.1
#### Fixes
-* Fix a couple of issues related to Android 12
-* Fix Navigate to Link interaction for API 30+
+* Fix a couple of issues related to Android 12.
+* Fix Navigate to Link interaction for API 30+.
+* Remove all references to AdvertiserId.
# 2021-08-04 - v5.7.0
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index dbff38ff8..9da4425c8 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -2,7 +2,7 @@
We love contributions!
-Any contributions to the master apptentive-ios project must sign the [Individual Contributor License Agreement (CLA)](https://docs.google.com/a/apptentive.com/spreadsheet/viewform?formkey=dDhMaXJKQnRoX0dRMzZNYnp5bk1Sbmc6MQ#gid=0). It's a doc that makes our lawyers happy and ensures we can provide a solid open source project.
+Any contributions to the master apptentive-android project must sign the [Individual Contributor License Agreement (CLA)](https://docs.google.com/a/apptentive.com/spreadsheet/viewform?formkey=dDhMaXJKQnRoX0dRMzZNYnp5bk1Sbmc6MQ#gid=0). It's a doc that makes our lawyers happy and ensures we can provide a solid open source project.
When you want to submit a change, send us a [pull request](https://github.com/apptentive/apptentive-android/pulls). Before we merge, we'll check to make sure you're on the list of people who've signed our CLA.
diff --git a/License.txt b/License.txt
index 52e5e1300..91bcd62d7 100644
--- a/License.txt
+++ b/License.txt
@@ -1,4 +1,4 @@
-Copyright (c) 2011-2019, Apptentive, Inc.
+Copyright (c) 2011-2021, Apptentive, Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without
diff --git a/README.md b/README.md
index a1bc73a4a..d30395749 100644
--- a/README.md
+++ b/README.md
@@ -7,13 +7,13 @@ use your app, to talk to them at the right time, and in the right way.
#### [Android Interface Customization](https://learn.apptentive.com/knowledge-base/android-interface-customization/)
-#### [Apptentive SDK API Javadoc](http://www.apptentive.com/docs/android/api)
+#### [Apptentive SDK API Javadoc](https://learn.apptentive.com/docs/android/api/index.html)
##### [API Changes here](docs/APIChanges.md)
##### [Release Notes](https://learn.apptentive.com/knowledge-base/android-sdk-release-notes/)
-##### Binary releases are hosted for Maven [here](http://search.maven.org/#artifactdetails|com.apptentive|apptentive-android|5.7.1|aar)
+##### Binary releases are hosted for Maven [here](http://search.maven.org/#artifactdetails|com.apptentive|apptentive-android|5.8.0|aar)
#### Reporting Bugs
diff --git a/apptentive/build.gradle b/apptentive/build.gradle
index 57a88d61a..a87b860f8 100644
--- a/apptentive/build.gradle
+++ b/apptentive/build.gradle
@@ -3,36 +3,30 @@ init()
apply plugin: 'com.android.library'
dependencies {
- implementation 'androidx.appcompat:appcompat:1.2.0'
- implementation 'androidx.legacy:legacy-support-v4:1.0.0'
- implementation 'androidx.cardview:cardview:1.0.0'
- implementation 'com.google.android.material:material:1.2.0'
+ implementation "androidx.appcompat:appcompat:$appcompat_library_version"
+ implementation "androidx.legacy:legacy-support-v4:$legacy_support_v4_version"
+ implementation "com.google.android.material:material:$material_design_version"
+ implementation "com.google.android.play:core:$play_core_version"
+ implementation "com.google.android.gms:play-services-base:$play_services_base_version"
- // Play Core library required for in-app review flow
- implementation 'com.google.android.play:core:1.8.0'
+ testImplementation "junit:junit:$junit_version"
+ testImplementation "org.powermock:powermock-module-junit4:$powermock_version"
+ testImplementation "org.powermock:powermock-module-junit4-rule:$powermock_version"
+ testImplementation "org.powermock:powermock-api-mockito2:$powermock_version"
+ testImplementation "org.powermock:powermock-classloading-xstream:$powermock_version"
- // Play Services library required to check for GPS availability before showing in-app review
- implementation 'com.google.android.gms:play-services-base:17.4.0'
-
- testImplementation 'junit:junit:4.13'
- testImplementation 'org.powermock:powermock-module-junit4:1.6.6'
- testImplementation 'org.powermock:powermock-module-junit4-rule:1.6.6'
- testImplementation 'org.powermock:powermock-api-mockito:1.6.6'
- testImplementation 'org.powermock:powermock-classloading-xstream:1.6.6'
-
- // Required for instrumented tests
- androidTestImplementation 'androidx.annotation:annotation:1.1.0'
- androidTestImplementation 'androidx.test:runner:1.3.0'
- androidTestImplementation 'androidx.test:rules:1.3.0'
+ androidTestImplementation "androidx.annotation:annotation:$annotation_version"
+ androidTestImplementation "androidx.test:runner:$androidx_test_version"
+ androidTestImplementation "androidx.test:rules:$androidx_test_version"
}
android {
- compileSdkVersion 30
- buildToolsVersion '30.0.2'
+ compileSdkVersion rootProject.compileSdkVersion
+ buildToolsVersion rootProject.buildToolsVersion
defaultConfig {
- minSdkVersion 14
- targetSdkVersion 30
+ minSdkVersion rootProject.minSdkVersion
+ targetSdkVersion rootProject.targetSdkVersion
// BUILD_NUMBER is provided by Jenkins. Default to 1 in dev builds.
versionCode System.getenv("BUILD_NUMBER") as Integer ?: System.getenv("TRAVIS_BUILD_NUMBER") as Integer ?: 1
versionName project.version
@@ -56,8 +50,8 @@ android {
}
compileOptions {
- sourceCompatibility JavaVersion.VERSION_1_7
- targetCompatibility JavaVersion.VERSION_1_7
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
}
testOptions {
diff --git a/apptentive/src/main/java/com/apptentive/android/sdk/ApptentiveBaseActivity.java b/apptentive/src/main/java/com/apptentive/android/sdk/ApptentiveBaseActivity.java
index 3c3248892..84edd6d14 100644
--- a/apptentive/src/main/java/com/apptentive/android/sdk/ApptentiveBaseActivity.java
+++ b/apptentive/src/main/java/com/apptentive/android/sdk/ApptentiveBaseActivity.java
@@ -29,8 +29,8 @@ protected void onCreate(@Nullable Bundle savedInstanceState) {
@Override
protected void onDestroy() {
- super.onDestroy();
unregisterNotification();
+ super.onDestroy();
}
//endregion
diff --git a/apptentive/src/main/java/com/apptentive/android/sdk/ApptentiveConfiguration.java b/apptentive/src/main/java/com/apptentive/android/sdk/ApptentiveConfiguration.java
index f88fe59ff..1b18c7d5c 100644
--- a/apptentive/src/main/java/com/apptentive/android/sdk/ApptentiveConfiguration.java
+++ b/apptentive/src/main/java/com/apptentive/android/sdk/ApptentiveConfiguration.java
@@ -12,6 +12,8 @@
import com.apptentive.android.sdk.module.engagement.interaction.model.TermsAndConditions;
import com.apptentive.android.sdk.util.StringUtils;
+import java.util.concurrent.TimeUnit;
+
public class ApptentiveConfiguration {
private final String apptentiveKey;
private final String apptentiveSignature;
@@ -23,6 +25,7 @@ public class ApptentiveConfiguration {
private Encryption encryption;
private boolean shouldCollectAndroidIdOnPreOreoTargets;
private TermsAndConditions surveyTermsAndConditions;
+ private Long interactionThrottle;
public ApptentiveConfiguration(@NonNull String apptentiveKey, @NonNull String apptentiveSignature) {
if (StringUtils.isNullOrEmpty(apptentiveKey)) {
@@ -150,4 +153,22 @@ public TermsAndConditions getSurveyTermsAndConditions() {
public void setSurveyTermsAndConditions(TermsAndConditions surveyTermsAndConditions) {
this.surveyTermsAndConditions = surveyTermsAndConditions;
}
+
+ public Long getInteractionThrottle() {
+ return interactionThrottle != null ? interactionThrottle : TimeUnit.DAYS.toMillis(7);
+ }
+
+ /**
+ * Sets a time limit throttle which determines when a rating interaction can be shown again.
+ * Default is 7 days.
+ *
+ * @see TimeUnit for conversion utils
+ * e.g. TimeUnit.MINUTES.toMillis(10); or TimeUnit.DAYS.toMillis(30);
+ *
+ * @param interactionThrottle The length of time (in milliseconds) to wait before showing
+ * the same interaction again.
+ */
+ public void setRatingInteractionThrottle(Long interactionThrottle) {
+ this.interactionThrottle = interactionThrottle;
+ }
}
diff --git a/apptentive/src/main/java/com/apptentive/android/sdk/ApptentiveInstance.java b/apptentive/src/main/java/com/apptentive/android/sdk/ApptentiveInstance.java
index 7c4869133..1e63cd32a 100644
--- a/apptentive/src/main/java/com/apptentive/android/sdk/ApptentiveInstance.java
+++ b/apptentive/src/main/java/com/apptentive/android/sdk/ApptentiveInstance.java
@@ -19,12 +19,14 @@
import com.apptentive.android.sdk.conversation.Conversation;
import com.apptentive.android.sdk.conversation.ConversationProxy;
import com.apptentive.android.sdk.module.engagement.interaction.InteractionManager;
+import com.apptentive.android.sdk.module.engagement.interaction.model.Interaction;
import com.apptentive.android.sdk.module.engagement.interaction.model.TermsAndConditions;
import com.apptentive.android.sdk.module.rating.IRatingProvider;
import com.apptentive.android.sdk.module.survey.OnSurveyFinishedListener;
import com.apptentive.android.sdk.storage.AppRelease;
import com.apptentive.android.sdk.storage.ApptentiveTaskManager;
import com.apptentive.android.sdk.util.Nullsafe;
+import com.apptentive.android.sdk.util.ThrottleUtils;
import java.util.Map;
@@ -73,4 +75,5 @@ public interface ApptentiveInstance extends Nullsafe {
String getDefaultAppDisplayName();
TermsAndConditions getSurveyTermsAndConditions();
+ boolean shouldThrottleInteraction(Interaction.Type interactionType);
}
diff --git a/apptentive/src/main/java/com/apptentive/android/sdk/ApptentiveInternal.java b/apptentive/src/main/java/com/apptentive/android/sdk/ApptentiveInternal.java
index d2717f9dc..95b56936d 100644
--- a/apptentive/src/main/java/com/apptentive/android/sdk/ApptentiveInternal.java
+++ b/apptentive/src/main/java/com/apptentive/android/sdk/ApptentiveInternal.java
@@ -40,6 +40,7 @@
import com.apptentive.android.sdk.model.LogoutPayload;
import com.apptentive.android.sdk.module.engagement.EngagementModule;
import com.apptentive.android.sdk.module.engagement.interaction.InteractionManager;
+import com.apptentive.android.sdk.module.engagement.interaction.model.Interaction;
import com.apptentive.android.sdk.module.engagement.interaction.model.MessageCenterInteraction;
import com.apptentive.android.sdk.module.engagement.interaction.model.TermsAndConditions;
import com.apptentive.android.sdk.module.messagecenter.MessageManager;
@@ -118,6 +119,8 @@ public class ApptentiveInternal implements ApptentiveInstance, ApptentiveNotific
// Used for temporarily holding customData that needs to be sent on the next message the consumer sends.
private Map customData;
+ private ThrottleUtils throttleUtils;
+
private static final String PUSH_ACTION = "action";
private static final String PUSH_CONVERSATION_ID = "conversation_id";
private static final int LOG_HISTORY_SIZE = 2;
@@ -176,6 +179,7 @@ private ApptentiveInternal(Application application, ApptentiveConfiguration conf
globalSharedPrefs = application.getSharedPreferences(Constants.PREF_NAME, Context.MODE_PRIVATE);
apptentiveHttpClient = new ApptentiveHttpClient(apptentiveKey, apptentiveSignature, getEndpointBase(globalSharedPrefs));
+ this.throttleUtils = new ThrottleUtils(configuration.getInteractionThrottle(), getGlobalSharedPrefs());
DeviceManager deviceManager = new DeviceManager(androidID);
conversationManager = new ConversationManager(appContext, Util.getInternalDir(appContext, CONVERSATIONS_DIR, true), encryption, deviceManager);
@@ -222,17 +226,6 @@ static void createInstance(@NonNull Application application, @NonNull Apptentive
// set log level before we initialize log monitor since log monitor can override it as well
ApptentiveLog.overrideLogLevel(configuration.getLogLevel());
- // troubleshooting mode
- if (configuration.isTroubleshootingModeEnabled()) {
- // initialize log writer
- ApptentiveLog.initializeLogWriter(application.getApplicationContext(), LOG_HISTORY_SIZE);
-
- // try initializing log monitor
- LogMonitor.startSession(application.getApplicationContext(), apptentiveKey, apptentiveSignature);
- } else {
- ApptentiveLog.i(TROUBLESHOOT, "Troubleshooting is disabled in the app configuration");
- }
-
synchronized (ApptentiveInternal.class) {
if (sApptentiveInternal == null) {
ApptentiveLog.i("Registering Apptentive Android SDK %s", Constants.getApptentiveSdkVersion());
@@ -240,10 +233,21 @@ static void createInstance(@NonNull Application application, @NonNull Apptentive
// resolve Android ID
boolean shouldGenerateRandomAndroidID = Build.VERSION.SDK_INT < Build.VERSION_CODES.O && !configuration.shouldCollectAndroidIdOnPreOreoTargets();
String androidID = resolveAndroidID(application.getApplicationContext(), shouldGenerateRandomAndroidID);
- sApptentiveInternal = new ApptentiveInternal(application, configuration, androidID);
dispatchOnConversationQueue(new DispatchTask() {
@Override
protected void execute() {
+ // troubleshooting mode
+ if (configuration.isTroubleshootingModeEnabled()) {
+ // initialize log writer
+ ApptentiveLog.initializeLogWriter(application.getApplicationContext(), LOG_HISTORY_SIZE);
+
+ // try initializing log monitor
+ LogMonitor.startSession(application.getApplicationContext(), apptentiveKey, apptentiveSignature);
+ } else {
+ ApptentiveLog.i(TROUBLESHOOT, "Troubleshooting is disabled in the app configuration");
+ }
+
+ sApptentiveInternal = new ApptentiveInternal(application, configuration, androidID);
sApptentiveInternal.start();
}
});
@@ -398,6 +402,11 @@ public TermsAndConditions getSurveyTermsAndConditions() {
return surveyTermsAndConditions;
}
+ @Override
+ public boolean shouldThrottleInteraction(Interaction.Type interactionType) {
+ return throttleUtils.shouldThrottleInteraction(interactionType);
+ }
+
public boolean isApptentiveDebuggable() {
return appRelease.isDebug();
}
diff --git a/apptentive/src/main/java/com/apptentive/android/sdk/ApptentiveNullInstance.java b/apptentive/src/main/java/com/apptentive/android/sdk/ApptentiveNullInstance.java
index ecbe7927d..9bc79b118 100644
--- a/apptentive/src/main/java/com/apptentive/android/sdk/ApptentiveNullInstance.java
+++ b/apptentive/src/main/java/com/apptentive/android/sdk/ApptentiveNullInstance.java
@@ -18,11 +18,13 @@
import com.apptentive.android.sdk.conversation.ConversationProxy;
import com.apptentive.android.sdk.debug.Assert;
import com.apptentive.android.sdk.module.engagement.interaction.InteractionManager;
+import com.apptentive.android.sdk.module.engagement.interaction.model.Interaction;
import com.apptentive.android.sdk.module.engagement.interaction.model.TermsAndConditions;
import com.apptentive.android.sdk.module.rating.IRatingProvider;
import com.apptentive.android.sdk.module.survey.OnSurveyFinishedListener;
import com.apptentive.android.sdk.storage.AppRelease;
import com.apptentive.android.sdk.storage.ApptentiveTaskManager;
+import com.apptentive.android.sdk.util.ThrottleUtils;
import java.util.Map;
@@ -216,6 +218,11 @@ public TermsAndConditions getSurveyTermsAndConditions() {
return null;
}
+ @Override
+ public boolean shouldThrottleInteraction(Interaction.Type interactionType) {
+ return false;
+ }
+
private void failMethodCall(String method) {
Assert.assertFail("Unable to invoke '%s': Apptentive SDK is not properly initialized", method);
}
diff --git a/apptentive/src/main/java/com/apptentive/android/sdk/conversation/Conversation.java b/apptentive/src/main/java/com/apptentive/android/sdk/conversation/Conversation.java
index 1d8e7dddf..56858d31c 100644
--- a/apptentive/src/main/java/com/apptentive/android/sdk/conversation/Conversation.java
+++ b/apptentive/src/main/java/com/apptentive/android/sdk/conversation/Conversation.java
@@ -134,6 +134,11 @@ public class Conversation implements DataChangedListener, Destroyable, DeviceDat
@Override
protected void execute() {
try {
+ if (ApptentiveLog.canLog(ApptentiveLog.Level.VERBOSE)) {
+ ApptentiveLog.v(CONVERSATION, "Saving conversation data...");
+ ApptentiveLog.v(CONVERSATION, "EventData: %s", getEventData().toString());
+ ApptentiveLog.v(CONVERSATION, "Messages: %s", messageManager.getMessageStore().toString());
+ }
saveConversationData();
} catch (Exception e) {
ApptentiveLog.e(CONVERSATION, e, "Exception while saving conversation data");
@@ -401,11 +406,6 @@ public void scheduleSaveConversationData() {
* if succeed.
*/
private synchronized void saveConversationData() throws SerializerException {
- if (ApptentiveLog.canLog(ApptentiveLog.Level.VERBOSE)) {
- ApptentiveLog.v(CONVERSATION, "Saving conversation data...");
- ApptentiveLog.v(CONVERSATION, "EventData: %s", getEventData().toString());
- ApptentiveLog.v(CONVERSATION, "Messages: %s", messageManager.getMessageStore().toString());
- }
long start = System.currentTimeMillis();
FileSerializer serializer = new EncryptedFileSerializer(conversationDataFile, encryption);
@@ -438,7 +438,7 @@ boolean migrateConversationData() throws SerializerException {
return false;
}
- void loadConversationData() throws SerializerException {
+ synchronized void loadConversationData() throws SerializerException {
long start = System.currentTimeMillis();
FileSerializer serializer = new EncryptedFileSerializer(conversationDataFile, encryption);
diff --git a/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/EngagementModule.java b/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/EngagementModule.java
index e02f76a9a..593cfab7b 100644
--- a/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/EngagementModule.java
+++ b/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/EngagementModule.java
@@ -19,6 +19,7 @@
import com.apptentive.android.sdk.model.ExtendedData;
import com.apptentive.android.sdk.module.engagement.interaction.model.Interaction;
import com.apptentive.android.sdk.module.engagement.interaction.model.MessageCenterInteraction;
+import com.apptentive.android.sdk.util.ThrottleUtils;
import com.apptentive.android.sdk.util.Util;
import com.apptentive.android.sdk.util.threading.DispatchTask;
@@ -90,7 +91,11 @@ private static boolean doEngage(Conversation conversation, Context context, Stri
Interaction interaction = conversation.getApplicableInteraction(eventLabel, true);
if (interaction != null) {
- return launchInteraction(context, conversation, interaction);
+ if (!ApptentiveInternal.getInstance().shouldThrottleInteraction(interaction.getType())) {
+ return launchInteraction(context, conversation, interaction);
+ } else {
+ return false;
+ }
}
ApptentiveLog.d(INTERACTIONS, "No interaction to show for event: '%s'", eventLabel);
return false;
diff --git a/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/interaction/fragment/AppStoreRatingFragment.java b/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/interaction/fragment/AppStoreRatingFragment.java
index e42a97753..37b29ac34 100644
--- a/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/interaction/fragment/AppStoreRatingFragment.java
+++ b/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/interaction/fragment/AppStoreRatingFragment.java
@@ -86,8 +86,8 @@ public void onActivityResult(int requestCode, int resultCode, Intent data) {
@Override
public void onPause() {
- super.onPause();
transit();
+ super.onPause();
}
@Override
diff --git a/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/interaction/fragment/ApptentiveBaseFragment.java b/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/interaction/fragment/ApptentiveBaseFragment.java
index a7f46ba01..524c9c0d2 100644
--- a/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/interaction/fragment/ApptentiveBaseFragment.java
+++ b/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/interaction/fragment/ApptentiveBaseFragment.java
@@ -242,7 +242,6 @@ public void onInteractionUpdated(boolean successful) {
@Override
public void onStop() {
- super.onStop();
try {
if (Build.VERSION.SDK_INT >= 11 && getActivity() != null) {
isChangingConfigurations = getActivity().isChangingConfigurations();
@@ -251,12 +250,11 @@ public void onStop() {
ApptentiveLog.e(e, "Exception in %s.onStop()", ApptentiveBaseFragment.class.getSimpleName());
logException(e);
}
+ super.onStop();
}
@Override
public void onDestroyView() {
- super.onDestroyView();
-
try {
if (toolbar != null && fragmentMenuItems != null) {
Menu toolbarMenu = toolbar.getMenu();
@@ -273,6 +271,7 @@ public void onDestroyView() {
logException(e);
}
+ super.onDestroyView();
}
@Override
diff --git a/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/interaction/fragment/MessageCenterFragment.java b/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/interaction/fragment/MessageCenterFragment.java
index b576983ac..7a19012c6 100644
--- a/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/interaction/fragment/MessageCenterFragment.java
+++ b/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/interaction/fragment/MessageCenterFragment.java
@@ -320,7 +320,6 @@ public void onStart() {
}
public void onStop() {
- super.onStop();
try {
ConversationProxy conversation = getConversation();
if (conversation != null) {
@@ -330,6 +329,7 @@ public void onStop() {
ApptentiveLog.e("Exception in %s.onStop()", MessageCenterFragment.class.getSimpleName());
logException(e);
}
+ super.onStop();
}
@Override
@@ -390,7 +390,6 @@ public void onActivityResult(int requestCode, int resultCode, Intent data) {
@Override
public void onPause() {
- super.onPause();
dispatchConversationTask(new ConversationDispatchTask() {
@Override
protected boolean execute(Conversation conversation) {
@@ -398,6 +397,7 @@ protected boolean execute(Conversation conversation) {
return true;
}
}, "pause message center fragment");
+ super.onPause();
}
@Override
diff --git a/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/interaction/fragment/NavigateToLinkFragment.java b/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/interaction/fragment/NavigateToLinkFragment.java
index 9c661b2a3..849db3262 100644
--- a/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/interaction/fragment/NavigateToLinkFragment.java
+++ b/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/interaction/fragment/NavigateToLinkFragment.java
@@ -83,8 +83,8 @@ public void onCreate(Bundle savedInstanceState) {
@Override
public void onPause() {
- super.onPause();
transit();
+ super.onPause();
}
diff --git a/apptentive/src/main/java/com/apptentive/android/sdk/storage/EncryptedFileSerializer.java b/apptentive/src/main/java/com/apptentive/android/sdk/storage/EncryptedFileSerializer.java
index edc860404..2d2e3cec3 100644
--- a/apptentive/src/main/java/com/apptentive/android/sdk/storage/EncryptedFileSerializer.java
+++ b/apptentive/src/main/java/com/apptentive/android/sdk/storage/EncryptedFileSerializer.java
@@ -6,6 +6,8 @@
package com.apptentive.android.sdk.storage;
+import static com.apptentive.android.sdk.util.ObjectUtils.isNullOrEmpty;
+
import com.apptentive.android.sdk.Encryption;
import com.apptentive.android.sdk.util.Util;
@@ -39,7 +41,11 @@ protected void serialize(FileOutputStream stream, Object object) throws Exceptio
oos.writeObject(object);
final byte[] unencryptedBytes = bos.toByteArray();
final byte[] encryptedBytes = encryption.encrypt(unencryptedBytes);
- stream.write(encryptedBytes); // TODO: should we write using a buffer?
+ if (!isNullOrEmpty(encryptedBytes)) {
+ stream.write(encryptedBytes); // TODO: should we write using a buffer?
+ } else {
+ throw new SerializerException(new IllegalStateException("Encrypted bytes should not be null or 0"));
+ }
} finally {
Util.ensureClosed(bos);
Util.ensureClosed(oos);
diff --git a/apptentive/src/main/java/com/apptentive/android/sdk/util/Constants.java b/apptentive/src/main/java/com/apptentive/android/sdk/util/Constants.java
index a11998acc..2ec24ac0d 100644
--- a/apptentive/src/main/java/com/apptentive/android/sdk/util/Constants.java
+++ b/apptentive/src/main/java/com/apptentive/android/sdk/util/Constants.java
@@ -9,7 +9,7 @@
public class Constants {
public static final int API_VERSION = 10;
- private static final String APPTENTIVE_SDK_VERSION = "5.7.1";
+ private static final String APPTENTIVE_SDK_VERSION = "5.8.0";
public static final int DEFAULT_CONNECT_TIMEOUT_MILLIS = 45000;
public static final int DEFAULT_READ_TIMEOUT_MILLIS = 45000;
diff --git a/apptentive/src/main/java/com/apptentive/android/sdk/util/ThrottleUtils.java b/apptentive/src/main/java/com/apptentive/android/sdk/util/ThrottleUtils.java
new file mode 100644
index 000000000..b1d8304ea
--- /dev/null
+++ b/apptentive/src/main/java/com/apptentive/android/sdk/util/ThrottleUtils.java
@@ -0,0 +1,47 @@
+package com.apptentive.android.sdk.util;
+
+import android.annotation.SuppressLint;
+import android.content.SharedPreferences;
+
+import com.apptentive.android.sdk.ApptentiveLog;
+import com.apptentive.android.sdk.module.engagement.interaction.model.Interaction;
+
+import java.util.concurrent.TimeUnit;
+
+public class ThrottleUtils {
+
+ public ThrottleUtils(Long ratingThrottle, SharedPreferences globalSharedPrefs) {
+ ratingThrottleLength = ratingThrottle;
+ sharedPrefs = globalSharedPrefs;
+ }
+
+ private final Long ratingThrottleLength;
+ private final SharedPreferences sharedPrefs;
+
+ private final long defaultThrottleLength = TimeUnit.SECONDS.toMillis(1);
+
+ @SuppressLint("ApplySharedPref")
+ public boolean shouldThrottleInteraction(Interaction.Type interactionType) {
+ String interactionName = interactionType.name();
+ long currentTime = System.currentTimeMillis();
+ long interactionLastThrottled = sharedPrefs.getLong(interactionName, 0);
+ boolean interactionIsRating = (interactionType == Interaction.Type.InAppRatingDialog
+ || interactionType == Interaction.Type.RatingDialog);
+
+ if ((interactionIsRating && (currentTime - interactionLastThrottled) < ratingThrottleLength)) {
+ logThrottle(interactionName, ratingThrottleLength, currentTime, interactionLastThrottled);
+ return true;
+ } else if (!interactionIsRating && (currentTime - interactionLastThrottled) < defaultThrottleLength) {
+ logThrottle(interactionName, defaultThrottleLength, currentTime, interactionLastThrottled);
+ return true;
+ } else {
+ sharedPrefs.edit().putLong(interactionName, currentTime).commit();
+ return false;
+ }
+ }
+
+ private void logThrottle(String interactionName, Long throttleLength, Long currentTime, Long lastThrottledTime) {
+ ApptentiveLog.w(interactionName + " throttled. Throttle length is " + throttleLength +
+ "ms. Can be shown again in " + (currentTime - lastThrottledTime) + "ms.");
+ }
+}
diff --git a/build.gradle b/build.gradle
index 1b1772890..1bf27f5b3 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,14 +1,62 @@
buildscript {
- ext.kotlin_version = '1.3.50'
+ ext {
+ // ----- SDK Compile and Build Versions ----- //
+
+ compileSdkVersion = 30
+ buildToolsVersion = '30.0.3'
+ minSdkVersion = 14
+ targetSdkVersion = 30
+
+ // ----- App dependencies ----- //
+
+ // AndroidX
+ // https://developer.android.com/jetpack/androidx/explorer
+ appcompat_library_version = '1.3.1'
+ legacy_support_v4_version = '1.0.0'
+
+ // Material Design
+ // https://github.com/material-components/material-components-android/releases
+ material_design_version='1.4.0'
+
+ // Google Play (For Google In-App Review)
+ // https://developer.android.com/guide/playcore
+ // https://developers.google.com/android/guides/setup
+ play_core_version = '1.10.2'
+ play_services_base_version = '17.6.0'
+
+
+ // ------- Testing ------- //
+
+ // Junit
+ // https://mvnrepository.com/artifact/junit/junit
+ junit_version = '4.13.2'
+
+ // PowerMock
+ // https://github.com/powermock/powermock
+ powermock_version = '2.0.9'
+
+ // AndroidX
+ // https://developer.android.com/jetpack/androidx/explorer
+ // https://developer.android.com/jetpack/androidx/releases/test
+ annotation_version = '1.2.0'
+ androidx_test_version = '1.4.0'
+ }
repositories {
google() // "https://maven.google.com"
mavenCentral()
}
dependencies {
+ // Android Gradle
+ // https://developer.android.com/studio/releases/gradle-plugin
classpath 'com.android.tools.build:gradle:4.2.2'
+
+ // Kotlin
+ // https://kotlinlang.org/docs/gradle.html
+ classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.30"
+
+ // HockeyApp
classpath 'com.github.3mph4515:gradle-hockeyapp-plugin:3.7.6'
- classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
diff --git a/samples/apptentive-example/build.gradle b/samples/apptentive-example/build.gradle
index d672914a8..7c18243b6 100644
--- a/samples/apptentive-example/build.gradle
+++ b/samples/apptentive-example/build.gradle
@@ -3,14 +3,13 @@ apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-android'
android {
- compileSdkVersion 29
- buildToolsVersion "29.0.2"
-
+ compileSdkVersion 30
+ buildToolsVersion "30.0.3"
defaultConfig {
applicationId "apptentive.com.example"
minSdkVersion 14
- targetSdkVersion 29
+ targetSdkVersion 30
versionCode 1
versionName "1.0"
@@ -23,22 +22,18 @@ android {
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
-
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
- implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
- implementation project(':apptentive')
+ implementation 'com.apptentive:apptentive-android:5.7.1'
+ implementation 'androidx.core:core-ktx:1.6.0'
+ implementation "androidx.appcompat:appcompat:1.3.1"
+ implementation 'androidx.constraintlayout:constraintlayout:2.1.0'
- implementation 'androidx.core:core-ktx:1.1.0'
- implementation 'androidx.appcompat:appcompat:1.1.0'
- implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
- testImplementation 'junit:junit:4.12'
- androidTestImplementation 'androidx.test.ext:junit:1.1.1'
- androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
-}
-repositories {
- mavenCentral()
+ testImplementation "junit:junit:4.13.2"
+
+ androidTestImplementation 'androidx.test.ext:junit:1.1.3'
+ androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
}
diff --git a/settings.gradle b/settings.gradle
index 9d6aca58d..892a83907 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -12,4 +12,6 @@ project(':apptentive-example').projectDir = new File('samples/apptentive-example
// Internal App
if (file('apptentive-internal-app/build.gradle').exists()) {
include ':apptentive-internal-app'
-}
\ No newline at end of file
+}
+
+rootProject.name = 'apptentive-sdk'
\ No newline at end of file
diff --git a/tests/test-app/build.gradle b/tests/test-app/build.gradle
index 47badd24f..3133dd000 100644
--- a/tests/test-app/build.gradle
+++ b/tests/test-app/build.gradle
@@ -6,7 +6,7 @@ android {
defaultConfig {
minSdkVersion 14
- targetSdkVersion 29
+ targetSdkVersion 30
versionCode 4
versionName "2.0"
}
@@ -25,7 +25,7 @@ android {
dependencies {
implementation project(':apptentive')
- androidTestImplementation 'junit:junit:4.12'
- androidTestImplementation 'androidx.test.ext:junit:1.1.1'
- androidTestImplementation 'androidx.test:rules:1.1.1'
+ androidTestImplementation 'junit:junit:4.13.2'
+ androidTestImplementation 'androidx.test.ext:junit:1.1.3'
+ androidTestImplementation 'androidx.test:rules:1.4.0'
}
\ No newline at end of file
diff --git a/tests/test-app/src/androidTest/java/com/apptentive/android/sdk/tests/misc/ThrottleUtilsTest.java b/tests/test-app/src/androidTest/java/com/apptentive/android/sdk/tests/misc/ThrottleUtilsTest.java
new file mode 100644
index 000000000..39502e1bd
--- /dev/null
+++ b/tests/test-app/src/androidTest/java/com/apptentive/android/sdk/tests/misc/ThrottleUtilsTest.java
@@ -0,0 +1,111 @@
+package com.apptentive.android.sdk.tests.misc;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+
+import com.apptentive.android.sdk.module.engagement.interaction.model.Interaction;
+import com.apptentive.android.sdk.tests.ApptentiveTestCaseBase;
+import com.apptentive.android.sdk.util.ThrottleUtils;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.concurrent.TimeUnit;
+
+public class ThrottleUtilsTest extends ApptentiveTestCaseBase {
+ private SharedPreferences sharedPreferences;
+ private ThrottleUtils throttleUtils;
+ Interaction.Type ratingInteraction = Interaction.Type.InAppRatingDialog;
+ Interaction.Type noteInteractionOne = Interaction.Type.TextModal;
+ Interaction.Type noteInteractionTwo = Interaction.Type.TextModal;
+ Interaction.Type surveyInteraction = Interaction.Type.Survey;
+
+ @Before
+ public void setUp() {
+ String APPTENTIVE_TEST_SHARED_PREF = "APPTENTIVE TEST SHARED PREF";
+ sharedPreferences = targetContext.getSharedPreferences(APPTENTIVE_TEST_SHARED_PREF, Context.MODE_PRIVATE);
+ throttleUtils = new ThrottleUtils(100L, sharedPreferences);
+ }
+
+ @After
+ public void tearDown() {
+ sharedPreferences = null;
+ }
+
+ @Test
+ public final void shouldThrottleRatingInteractionTest() {
+ try {
+ // First call
+ assertFalse(throttleUtils.shouldThrottleInteraction(ratingInteraction));
+
+ // Call right after
+ assertTrue(throttleUtils.shouldThrottleInteraction(ratingInteraction));
+ TimeUnit.MILLISECONDS.sleep(10L);
+
+ // 10ms since first call
+ assertTrue(throttleUtils.shouldThrottleInteraction(ratingInteraction));
+ TimeUnit.MILLISECONDS.sleep(50L);
+
+ // 60ms since first call
+ assertTrue(throttleUtils.shouldThrottleInteraction(ratingInteraction));
+ TimeUnit.MILLISECONDS.sleep(60L);
+
+ // 120ms since first call (should be able to call again)
+ assertFalse(throttleUtils.shouldThrottleInteraction(ratingInteraction));
+ TimeUnit.MILLISECONDS.sleep(50L);
+
+ // 50ms since second call
+ assertTrue(throttleUtils.shouldThrottleInteraction(ratingInteraction));
+ } catch (Exception e) {
+
+ }
+ }
+
+ @Test
+ public final void shouldThrottleInteractionWithOtherInteractionsTest() {
+ try {
+ // Default throttle length is 1 second aka 1000 ms
+
+ // First call interactionTwo
+ assertFalse(throttleUtils.shouldThrottleInteraction(noteInteractionOne));
+ TimeUnit.MILLISECONDS.sleep(300L);
+
+ // 300ms since first call interactionTwo
+ assertTrue(throttleUtils.shouldThrottleInteraction(noteInteractionOne));
+
+ // Same Type as interactionTwo (so 300ms since last called this type)
+ assertTrue(throttleUtils.shouldThrottleInteraction(noteInteractionTwo));
+
+ // first call interactionFour
+ assertFalse(throttleUtils.shouldThrottleInteraction(surveyInteraction));
+ TimeUnit.MILLISECONDS.sleep(500L);
+
+ // 800ms since second call interactionTwo
+ assertTrue(throttleUtils.shouldThrottleInteraction(noteInteractionOne));
+ assertTrue(throttleUtils.shouldThrottleInteraction(noteInteractionTwo));
+ TimeUnit.MILLISECONDS.sleep(300L);
+
+ // 1100ms since first call of interactionTwo (should be able to call)
+ assertFalse(throttleUtils.shouldThrottleInteraction(noteInteractionTwo));
+
+ // Same type as interactionThree that was just called (shouldn't be able to call)
+ assertTrue(throttleUtils.shouldThrottleInteraction(noteInteractionOne));
+
+ // 800ms since first call of interactionFour
+ assertTrue(throttleUtils.shouldThrottleInteraction(surveyInteraction));
+ TimeUnit.MILLISECONDS.sleep(300L);
+
+ // 1100ms since first call of interactionFour
+ assertFalse(throttleUtils.shouldThrottleInteraction(surveyInteraction));
+
+ // Call right after same interaction should not call
+ assertTrue(throttleUtils.shouldThrottleInteraction(surveyInteraction));
+ } catch (Exception e) {
+
+ }
+ }
+}
diff --git a/tests/test-app/src/androidTest/java/com/apptentive/android/sdk/tests/module/engagement/InteractionTest.java b/tests/test-app/src/androidTest/java/com/apptentive/android/sdk/tests/module/engagement/InteractionTest.java
index ed33a6e43..989cc6c4e 100644
--- a/tests/test-app/src/androidTest/java/com/apptentive/android/sdk/tests/module/engagement/InteractionTest.java
+++ b/tests/test-app/src/androidTest/java/com/apptentive/android/sdk/tests/module/engagement/InteractionTest.java
@@ -6,13 +6,16 @@
package com.apptentive.android.sdk.tests.module.engagement;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
import androidx.test.runner.AndroidJUnit4;
import com.apptentive.android.sdk.ApptentiveLog;
import com.apptentive.android.sdk.module.engagement.interaction.model.InteractionCriteria;
import com.apptentive.android.sdk.module.engagement.logic.DefaultRandomPercentProvider;
import com.apptentive.android.sdk.module.engagement.logic.FieldManager;
-import com.apptentive.android.sdk.module.engagement.logic.RandomPercentProvider;
import com.apptentive.android.sdk.storage.AppRelease;
import com.apptentive.android.sdk.storage.AppReleaseManager;
import com.apptentive.android.sdk.storage.Device;
@@ -28,10 +31,6 @@
import java.io.File;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
/**
* Note: Right now, these tests need versionName and versionCode in the manifest to be "2.0" and 4", respectively.
*/
@@ -160,7 +159,7 @@ public void criteriaApplicationVersionCode() throws JSONException {
String json = loadTextAssetAsString(TEST_DATA_DIR + "criteria/testCriteriaApplicationVersionCode.json");
json = json.replace("\"APPLICATION_VERSION_CODE\"", String.valueOf(appRelease.getVersionCode()));
InteractionCriteria criteria = new InteractionCriteria(json);
- FieldManager fieldManager = new FieldManager(targetContext, new VersionHistory(), new EventData(), new Person(), new Device(), appRelease , new DefaultRandomPercentProvider(targetContext, "id"));
+ FieldManager fieldManager = new FieldManager(targetContext, new VersionHistory(), new EventData(), new Person(), new Device(), appRelease, new DefaultRandomPercentProvider(targetContext, "id"));
assertTrue(criteria.isMet(fieldManager));
}
@@ -171,7 +170,7 @@ public void criteriaApplicationVersionName() throws JSONException {
String json = loadTextAssetAsString(TEST_DATA_DIR + "criteria/testCriteriaApplicationVersionName.json");
json = json.replace("APPLICATION_VERSION_NAME", appRelease.getVersionName());
InteractionCriteria criteria = new InteractionCriteria(json);
- FieldManager fieldManager = new FieldManager(targetContext, new VersionHistory(), new EventData(), new Person(), new Device(), appRelease , new DefaultRandomPercentProvider(targetContext, "id"));
+ FieldManager fieldManager = new FieldManager(targetContext, new VersionHistory(), new EventData(), new Person(), new Device(), appRelease, new DefaultRandomPercentProvider(targetContext, "id"));
assertTrue(criteria.isMet(fieldManager));
}
@@ -181,7 +180,7 @@ public void criteriaApplicationDebug() throws JSONException {
String json = loadTextAssetAsString(TEST_DATA_DIR + "criteria/testCriteriaApplicationDebug.json");
json = json.replace("APPLICATION_DEBUG", Boolean.toString(appRelease.isDebug()));
InteractionCriteria criteria = new InteractionCriteria(json);
- FieldManager fieldManager = new FieldManager(targetContext, new VersionHistory(), new EventData(), new Person(), new Device(), appRelease , new DefaultRandomPercentProvider(targetContext, "id"));
+ FieldManager fieldManager = new FieldManager(targetContext, new VersionHistory(), new EventData(), new Person(), new Device(), appRelease, new DefaultRandomPercentProvider(targetContext, "id"));
assertTrue(criteria.isMet(fieldManager));
}
@@ -199,7 +198,7 @@ public void criteriaProcessingPerformance() throws JSONException {
VersionHistory versionHistory = new VersionHistory();
EventData eventData = new EventData();
- FieldManager fieldManager = new FieldManager(targetContext, versionHistory, eventData, new Person(), new Device(), new AppRelease() , new DefaultRandomPercentProvider(targetContext, "id"));
+ FieldManager fieldManager = new FieldManager(targetContext, versionHistory, eventData, new Person(), new Device(), new AppRelease(), new DefaultRandomPercentProvider(targetContext, "id"));
versionHistory.updateVersionHistory(Util.currentTimeSeconds(), versionCode, versionName);
eventData.storeEventForCurrentAppVersion(Util.currentTimeSeconds(), versionCode, versionName, "app.launch");
eventData.storeEventForCurrentAppVersion(Util.currentTimeSeconds(), versionCode, versionName, "app.launch");
@@ -232,7 +231,7 @@ public void savingCodePointAndCheckingForApplicableInteraction() throws JSONExce
InteractionCriteria criteria = new InteractionCriteria(json);
EventData eventData = new EventData();
- FieldManager fieldManager = new FieldManager(targetContext, new VersionHistory(), eventData, new Person(), new Device(), new AppRelease() , new DefaultRandomPercentProvider(targetContext, "id"));
+ FieldManager fieldManager = new FieldManager(targetContext, new VersionHistory(), eventData, new Person(), new Device(), new AppRelease(), new DefaultRandomPercentProvider(targetContext, "id"));
eventData.storeEventForCurrentAppVersion(Util.currentTimeSeconds(), versionCode, versionName, "app.launch");
eventData.storeEventForCurrentAppVersion(Util.currentTimeSeconds(), versionCode, versionName, "app.launch");
eventData.storeEventForCurrentAppVersion(Util.currentTimeSeconds(), versionCode, versionName, "big.win");
@@ -308,7 +307,7 @@ public void upgradeMessageOnVersionCode() throws JSONException {
InteractionCriteria criteria = new InteractionCriteria(json);
VersionHistory versionHistory = new VersionHistory();
- FieldManager fieldManager = new FieldManager(targetContext, versionHistory, new EventData(), new Person(), new Device(), appRelease , new DefaultRandomPercentProvider(targetContext, "id"));
+ FieldManager fieldManager = new FieldManager(targetContext, versionHistory, new EventData(), new Person(), new Device(), appRelease, new DefaultRandomPercentProvider(targetContext, "id"));
versionHistory.updateVersionHistory(Util.currentTimeSeconds(), versionCode, versionName);
// Test version targeted UpgradeMessage
@@ -344,7 +343,7 @@ public void upgradeMessageOnVersionName() throws JSONException {
VersionHistory versionHistory = new VersionHistory();
EventData eventData = new EventData();
- FieldManager fieldManager = new FieldManager(targetContext, versionHistory, eventData, new Person(), new Device(), appRelease , new DefaultRandomPercentProvider(targetContext, "id"));
+ FieldManager fieldManager = new FieldManager(targetContext, versionHistory, eventData, new Person(), new Device(), appRelease, new DefaultRandomPercentProvider(targetContext, "id"));
versionHistory.updateVersionHistory(Util.currentTimeSeconds(), versionCode, versionName);
eventData.storeEventForCurrentAppVersion(Util.currentTimeSeconds(), versionCode, versionName, "app.launch");