From 7596d718fa63dda0e1d5cb683749acfc6691b295 Mon Sep 17 00:00:00 2001 From: Abhishek Pandey <64667840+1abhishekpandey@users.noreply.github.com> Date: Thu, 9 Nov 2023 12:51:38 +0530 Subject: [PATCH 1/3] fix: update lastActiveTimestamp value when reset call is made (#360) * refactor: change `updateLastEventTimeStamp` to `updateLastActiveTimestamp` * chore: make session variable of type final To fix warnings * fix: update last active timestamp when reset is made This fix might change in future based on the discussion * refactor: change LastEventTimeStamp to LastActiveTimestamp --- .../sdk/core/RudderPreferenceManager.java | 14 ++++++------- .../android/sdk/core/RudderUserSession.java | 20 +++++++++---------- .../sdk/core/RudderUserSessionManager.java | 9 ++++++--- 3 files changed, 23 insertions(+), 20 deletions(-) diff --git a/core/src/main/java/com/rudderstack/android/sdk/core/RudderPreferenceManager.java b/core/src/main/java/com/rudderstack/android/sdk/core/RudderPreferenceManager.java index 2370b47bc..a67f2ed6b 100644 --- a/core/src/main/java/com/rudderstack/android/sdk/core/RudderPreferenceManager.java +++ b/core/src/main/java/com/rudderstack/android/sdk/core/RudderPreferenceManager.java @@ -27,7 +27,7 @@ class RudderPreferenceManager { private static final String RUDDER_OPT_OUT_TIME_KEY = "rl_opt_out_time"; private static final String RUDDER_ANONYMOUS_ID_KEY = "rl_anonymous_id_key"; private static final String RUDDER_PERIODIC_WORK_REQUEST_ID_KEY = "rl_periodic_work_request_key"; - private static final String RUDDER_LAST_EVENT_TIMESTAMP_KEY = "rl_last_event_timestamp_key"; + private static final String RUDDER_LAST_ACTIVE_TIMESTAMP_KEY = "rl_last_event_timestamp_key"; private static final String RUDDER_SESSION_ID_KEY = "rl_session_id_key"; private static final String RUDDER_AUTO_SESSION_TRACKING_STATUS_KEY = "rl_auto_session_tracking_status_key"; private static final String RUDDER_DMT_HEADER_KEY = "rl_dmt_header_key"; @@ -157,18 +157,18 @@ long getOptOutTime() { return preferences.getLong(RUDDER_OPT_OUT_TIME_KEY, -1); } - void saveLastEventTimeStamp(Long time) { - preferences.edit().putLong(RUDDER_LAST_EVENT_TIMESTAMP_KEY, time).apply(); + void saveLastActiveTimestamp(Long time) { + preferences.edit().putLong(RUDDER_LAST_ACTIVE_TIMESTAMP_KEY, time).apply(); } @Nullable - Long getLastEventTimeStamp() { - long time = preferences.getLong(RUDDER_LAST_EVENT_TIMESTAMP_KEY, -1); + Long getLastActiveTimestamp() { + long time = preferences.getLong(RUDDER_LAST_ACTIVE_TIMESTAMP_KEY, -1); return (time == -1) ? null : new Long(time); } - void clearLastEventTimeStamp() { - preferences.edit().remove(RUDDER_LAST_EVENT_TIMESTAMP_KEY).apply(); + void clearLastActiveTimestamp() { + preferences.edit().remove(RUDDER_LAST_ACTIVE_TIMESTAMP_KEY).apply(); } void saveSessionId(Long sessionId) { diff --git a/core/src/main/java/com/rudderstack/android/sdk/core/RudderUserSession.java b/core/src/main/java/com/rudderstack/android/sdk/core/RudderUserSession.java index 9d84eebe8..ed29dea52 100644 --- a/core/src/main/java/com/rudderstack/android/sdk/core/RudderUserSession.java +++ b/core/src/main/java/com/rudderstack/android/sdk/core/RudderUserSession.java @@ -10,14 +10,14 @@ class RudderUserSession { private final RudderConfig config; private Long sessionId; private boolean sessionStart; - private Long lastEventTimeStamp; - private RudderPreferenceManager preferenceManager; + private Long lastActiveTimestamp; + private final RudderPreferenceManager preferenceManager; RudderUserSession(RudderPreferenceManager _preferenceManager, RudderConfig _config) { this.config = _config; this.preferenceManager = _preferenceManager; this.sessionId = _preferenceManager.getSessionId(); - this.lastEventTimeStamp = _preferenceManager.getLastEventTimeStamp(); + this.lastActiveTimestamp = _preferenceManager.getLastActiveTimestamp(); } public void startSession() { @@ -35,13 +35,13 @@ public void startSession(Long sessionId) { public void startSessionIfNeeded() { - if (this.lastEventTimeStamp == null) { + if (this.lastActiveTimestamp == null) { this.startSession(); return; } final long timeDifference; synchronized (this) { - timeDifference = Math.abs((Utils.getCurrentTimeInMilliSeconds() - this.lastEventTimeStamp)); + timeDifference = Math.abs((Utils.getCurrentTimeInMilliSeconds() - this.lastActiveTimestamp)); } if (timeDifference > this.config.getSessionTimeout()) { refreshSession(); @@ -53,9 +53,9 @@ public void refreshSession() { this.startSession(); } - public synchronized void updateLastEventTimeStamp() { - this.lastEventTimeStamp = Utils.getCurrentTimeInMilliSeconds(); - this.preferenceManager.saveLastEventTimeStamp(this.lastEventTimeStamp); + public synchronized void updateLastActiveTimestamp() { + this.lastActiveTimestamp = Utils.getCurrentTimeInMilliSeconds(); + this.preferenceManager.saveLastActiveTimestamp(this.lastActiveTimestamp); } @Nullable @@ -75,7 +75,7 @@ public synchronized void clearSession() { this.sessionId = null; this.preferenceManager.clearSessionId(); this.sessionStart = true; - this.lastEventTimeStamp = null; - this.preferenceManager.clearLastEventTimeStamp(); + this.lastActiveTimestamp = null; + this.preferenceManager.clearLastActiveTimestamp(); } } diff --git a/core/src/main/java/com/rudderstack/android/sdk/core/RudderUserSessionManager.java b/core/src/main/java/com/rudderstack/android/sdk/core/RudderUserSessionManager.java index 4c4c42ed6..da7e449b6 100644 --- a/core/src/main/java/com/rudderstack/android/sdk/core/RudderUserSessionManager.java +++ b/core/src/main/java/com/rudderstack/android/sdk/core/RudderUserSessionManager.java @@ -4,8 +4,8 @@ public class RudderUserSessionManager { private RudderUserSession userSession; - private RudderPreferenceManager preferenceManager; - private RudderConfig config; + private final RudderPreferenceManager preferenceManager; + private final RudderConfig config; public RudderUserSessionManager(RudderPreferenceManager preferenceManager, RudderConfig config) { this.preferenceManager = preferenceManager; @@ -44,7 +44,7 @@ void applySessionTracking(RudderMessage message) { message.setSession(userSession); } if (isAutomaticSessionTrackingEnabled()) { - userSession.updateLastEventTimeStamp(); + userSession.updateLastActiveTimestamp(); } } @@ -79,6 +79,9 @@ Long getSessionId() { public void reset() { if (getSessionId() != null) { userSession.refreshSession(); + if (isAutomaticSessionTrackingEnabled()) { + userSession.updateLastActiveTimestamp(); + } } } } From c9bb58f7e2e2b76f9aaed817e36d5f46c3b86bab Mon Sep 17 00:00:00 2001 From: Desu Sai Venkat <48179357+desusai7@users.noreply.github.com> Date: Tue, 14 Nov 2023 13:39:50 +0530 Subject: [PATCH 2/3] feat: added support for JSONObject and JSONArray as part of RudderMessage object (#350) * feat: added support for JSONObject and JSONArray as part of RudderMessage * chore: minor improvements * test: added unit tests for getEventJsonString in EventRepository class * refactor: created a singleton instance of gson to use it across the sdk * fix: using singleton instance of gson across all points * test: added unit tests for Singleton gson serialization in java * test: increased gson serialization test timeouts * test: replace usage of powermockito with mockito in RudderGsonTest --------- Co-authored-by: Desu Sai Venkat --- .../android/sdk/core/EventRepository.java | 16 +- .../android/sdk/core/RudderClient.java | 1 - .../android/sdk/core/RudderContext.java | 17 +- .../sdk/core/RudderDeviceModeManager.java | 15 +- ...RudderDeviceModeTransformationManager.java | 15 +- .../android/sdk/core/RudderMessage.java | 6 + .../sdk/core/RudderPreferenceManager.java | 4 +- .../sdk/core/RudderServerConfigManager.java | 4 +- .../android/sdk/core/RudderTraits.java | 6 +- .../TransformationResponseDeserializer.java | 12 +- .../core/ecomm/events/CartViewedEvent.java | 4 +- .../ecomm/events/CheckoutStartedEvent.java | 4 +- .../events/CheckoutStepCompletedEvent.java | 4 +- .../ecomm/events/CheckoutStepViewedEvent.java | 4 +- .../ecomm/events/OrderCancelledEvent.java | 4 +- .../ecomm/events/OrderCompletedEvent.java | 4 +- .../core/ecomm/events/OrderRefundedEvent.java | 4 +- .../core/ecomm/events/OrderUpdatedEvent.java | 4 +- .../ecomm/events/ProductAddedToCartEvent.java | 4 +- .../events/ProductAddedToWishListEvent.java | 4 +- .../ecomm/events/ProductClickedEvent.java | 4 +- .../events/ProductListFilteredEvent.java | 8 +- .../ecomm/events/ProductListViewedEvent.java | 4 +- .../ecomm/events/ProductRemovedEvent.java | 4 +- .../ProductRemovedFromWishListEvent.java | 4 +- .../core/ecomm/events/ProductSharedEvent.java | 4 +- .../core/ecomm/events/ProductViewedEvent.java | 4 +- .../ecomm/events/PromotionClickedEvent.java | 4 +- .../ecomm/events/PromotionViewedEvent.java | 4 +- .../WishListProductAddedToCartEvent.java | 4 +- .../android/sdk/core/gson/RudderGson.java | 33 +++ .../RudderContextTypeAdapter.java} | 6 +- .../RudderJSONArrayTypeAdapter.java | 44 +++ .../RudderJSONObjectTypeAdapter.java | 49 ++++ .../RudderTraitsTypeAdapter.java} | 6 +- .../android/sdk/core/util/Utils.java | 15 +- .../sdk/core/DBPersistentManagerTest.java | 19 +- .../android/sdk/core/EventRepositoryTest.java | 128 +++++++- .../android/sdk/core/ReflectionUtils.java | 6 + .../android/sdk/core/RudderGsonTest.java | 274 ++++++++++++++++++ .../dummy/DummyGAIntegrationImpl.java | 3 - 41 files changed, 626 insertions(+), 137 deletions(-) create mode 100644 core/src/main/java/com/rudderstack/android/sdk/core/gson/RudderGson.java rename core/src/main/java/com/rudderstack/android/sdk/core/{util/RudderContextSerializer.java => gson/gsonadapters/RudderContextTypeAdapter.java} (91%) create mode 100644 core/src/main/java/com/rudderstack/android/sdk/core/gson/gsonadapters/RudderJSONArrayTypeAdapter.java create mode 100644 core/src/main/java/com/rudderstack/android/sdk/core/gson/gsonadapters/RudderJSONObjectTypeAdapter.java rename core/src/main/java/com/rudderstack/android/sdk/core/{util/RudderTraitsSerializer.java => gson/gsonadapters/RudderTraitsTypeAdapter.java} (91%) create mode 100644 core/src/test/java/com/rudderstack/android/sdk/core/RudderGsonTest.java diff --git a/core/src/main/java/com/rudderstack/android/sdk/core/EventRepository.java b/core/src/main/java/com/rudderstack/android/sdk/core/EventRepository.java index 7f4cbcef4..097c1cc4e 100644 --- a/core/src/main/java/com/rudderstack/android/sdk/core/EventRepository.java +++ b/core/src/main/java/com/rudderstack/android/sdk/core/EventRepository.java @@ -20,12 +20,9 @@ import androidx.annotation.VisibleForTesting; import androidx.lifecycle.ProcessLifecycleOwner; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; import com.rudderstack.android.sdk.core.consent.ConsentFilterHandler; import com.rudderstack.android.sdk.core.consent.RudderConsentFilter; -import com.rudderstack.android.sdk.core.util.RudderContextSerializer; -import com.rudderstack.android.sdk.core.util.RudderTraitsSerializer; +import com.rudderstack.android.sdk.core.gson.RudderGson; import com.rudderstack.android.sdk.core.util.Utils; import java.io.UnsupportedEncodingException; @@ -63,11 +60,6 @@ class EventRepository { private @Nullable ConsentFilterHandler consentFilterHandler = null; - - private final Gson gson = new GsonBuilder() - .registerTypeAdapter(RudderTraits.class, new RudderTraitsSerializer()) - .registerTypeAdapter(RudderContext.class, new RudderContextSerializer()) - .create(); private String dataPlaneUrl; private final String writeKey; @@ -347,7 +339,7 @@ void processMessage(@NonNull RudderMessage message) { RudderMessage updatedMessage = updateMessageWithConsentedDestinations(message); userSessionManager.applySessionTracking(updatedMessage); - String eventJson = gson.toJson(updatedMessage); + String eventJson = getEventJsonString(updatedMessage); RudderLogger.logVerbose(String.format(Locale.US, "EventRepository: dump: message: %s", eventJson)); if (isMessageJsonExceedingMaxSize(eventJson)) { incrementDiscardedCounter(1, Collections.singletonMap(LABEL_TYPE, ReportManager.LABEL_TYPE_MSG_SIZE_INVALID)); @@ -357,6 +349,10 @@ void processMessage(@NonNull RudderMessage message) { dbManager.saveEvent(eventJson, new EventInsertionCallback(message, deviceModeManager)); } + String getEventJsonString(RudderMessage updatedMessage) { + return RudderGson.getInstance().toJson(updatedMessage); + } + private boolean isMessageJsonExceedingMaxSize(String eventJson) { return Utils.getUTF8Length(eventJson) > Utils.MAX_EVENT_SIZE; } diff --git a/core/src/main/java/com/rudderstack/android/sdk/core/RudderClient.java b/core/src/main/java/com/rudderstack/android/sdk/core/RudderClient.java index f21db5110..bc617ec12 100644 --- a/core/src/main/java/com/rudderstack/android/sdk/core/RudderClient.java +++ b/core/src/main/java/com/rudderstack/android/sdk/core/RudderClient.java @@ -11,7 +11,6 @@ import androidx.annotation.Nullable; import com.rudderstack.android.sdk.core.util.Utils; -import com.rudderstack.gsonrudderadapter.GsonAdapter; import java.util.Collections; import java.util.Map; diff --git a/core/src/main/java/com/rudderstack/android/sdk/core/RudderContext.java b/core/src/main/java/com/rudderstack/android/sdk/core/RudderContext.java index b47357a55..9fb525dc7 100644 --- a/core/src/main/java/com/rudderstack/android/sdk/core/RudderContext.java +++ b/core/src/main/java/com/rudderstack/android/sdk/core/RudderContext.java @@ -8,12 +8,9 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import androidx.annotation.VisibleForTesting; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; import com.google.gson.annotations.SerializedName; -import com.rudderstack.android.sdk.core.util.RudderTraitsSerializer; +import com.rudderstack.android.sdk.core.gson.RudderGson; import com.rudderstack.android.sdk.core.util.Utils; import java.util.ArrayList; @@ -89,7 +86,7 @@ public class RudderContext { RudderLogger.logDebug(String.format(Locale.US, "Traits from persistence storage%s", traitsJson)); if (traitsJson == null) { RudderTraits traits = new RudderTraits(anonymousId); - this.traits = Utils.convertToMap(new Gson().toJson(traits)); + this.traits = Utils.convertToMap(RudderGson.getInstance().toJson(traits)); this.persistTraits(); RudderLogger.logDebug("New traits has been saved"); } else { @@ -121,8 +118,7 @@ public class RudderContext { void resetTraits() { RudderTraits traits = new RudderTraits(); // convert the whole traits to map and take care of the extras - Gson gson = new GsonBuilder().registerTypeAdapter(RudderTraits.class, new RudderTraitsSerializer()).create(); - this.traits = Utils.convertToMap(gson.toJson(traits)); + this.traits = Utils.convertToMap(RudderGson.getInstance().toJson(traits)); } void updateTraits(RudderTraits traits) { @@ -132,8 +128,7 @@ void updateTraits(RudderTraits traits) { } // convert the whole traits to map and take care of the extras - Gson gson = new GsonBuilder().registerTypeAdapter(RudderTraits.class, new RudderTraitsSerializer()).create(); - Map traitsMap = Utils.convertToMap(gson.toJson(traits)); + Map traitsMap = Utils.convertToMap(RudderGson.getInstance().toJson(traits)); String existingId = (String) this.traits.get("id"); String newId = (String) traitsMap.get("id"); @@ -159,7 +154,7 @@ void persistTraits() { try { if (RudderClient.getApplication() != null) { RudderPreferenceManager preferenceManger = RudderPreferenceManager.getInstance(RudderClient.getApplication()); - preferenceManger.saveTraits(new Gson().toJson(this.traits)); + preferenceManger.saveTraits(RudderGson.getInstance().toJson(this.traits)); } } catch (NullPointerException ex) { ReportManager.reportError(ex); @@ -340,7 +335,7 @@ void persistExternalIds() { try { if (RudderClient.getApplication() != null) { RudderPreferenceManager preferenceManger = RudderPreferenceManager.getInstance(RudderClient.getApplication()); - preferenceManger.saveExternalIds(new Gson().toJson(this.externalIds)); + preferenceManger.saveExternalIds(RudderGson.getInstance().toJson(this.externalIds)); } } catch (NullPointerException ex) { ReportManager.reportError(ex); diff --git a/core/src/main/java/com/rudderstack/android/sdk/core/RudderDeviceModeManager.java b/core/src/main/java/com/rudderstack/android/sdk/core/RudderDeviceModeManager.java index 6e4229beb..2cdc5a828 100644 --- a/core/src/main/java/com/rudderstack/android/sdk/core/RudderDeviceModeManager.java +++ b/core/src/main/java/com/rudderstack/android/sdk/core/RudderDeviceModeManager.java @@ -6,13 +6,9 @@ import static com.rudderstack.android.sdk.core.TransformationResponse.TransformedDestination; import static com.rudderstack.android.sdk.core.TransformationRequest.TransformationRequestEvent; import static com.rudderstack.android.sdk.core.util.Utils.MAX_FLUSH_QUEUE_SIZE; -import static com.rudderstack.android.sdk.core.util.Utils.getBooleanFromMap; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; import com.rudderstack.android.sdk.core.consent.ConsentFilterHandler; -import com.rudderstack.android.sdk.core.util.RudderContextSerializer; -import com.rudderstack.android.sdk.core.util.RudderTraitsSerializer; +import com.rudderstack.android.sdk.core.gson.RudderGson; import com.rudderstack.android.sdk.core.util.Utils; import java.util.ArrayList; @@ -54,11 +50,6 @@ public class RudderDeviceModeManager { RudderDeviceModeTransformationManager deviceModeTransformationManager; private boolean areDeviceModeFactoriesAbsent = false; - static final Gson gson = new GsonBuilder() - .registerTypeAdapter(RudderTraits.class, new RudderTraitsSerializer()) - .registerTypeAdapter(RudderContext.class, new RudderContextSerializer()) - .create(); - RudderDeviceModeManager(DBPersistentManager dbPersistentManager, RudderNetworkManager networkManager, RudderConfig rudderConfig, RudderDataResidencyManager dataResidencyManager) { this.dbPersistentManager = dbPersistentManager; this.networkManager = networkManager; @@ -251,7 +242,7 @@ private void replayMessageQueue() { RudderLogger.logDebug(String.format(Locale.US, "RudderDeviceModeManager: replayMessageQueue: replaying old messages with factories. Count: %d", messageIds.size())); for (int i = 0; i < messageIds.size(); i++) { try { - RudderMessage message = gson.fromJson(messages.get(i), RudderMessage.class); + RudderMessage message = RudderGson.getInstance().fromJson(messages.get(i), RudderMessage.class); makeFactoryDump(message, messageIds.get(i), true); } catch (Exception e) { ReportManager.reportError(e); @@ -311,7 +302,7 @@ void dumpEventToDestinations(RudderMessage message, List destinations, S if (integration != null) { try { RudderLogger.logDebug(String.format(Locale.US, "RudderDeviceModeManager: %s: dumping event %s for %s", logTag, message.getEventName(), destinationName)); - RudderLogger.logVerbose(String.format(Locale.US, "RudderDeviceModeManager: Dumping: %s", gson.toJson(message))); + RudderLogger.logVerbose(String.format(Locale.US, "RudderDeviceModeManager: Dumping: %s", RudderGson.getInstance().toJson(message))); addDeviceModeCounter(message.getType(), destinationName); integration.dump(message); } catch (Exception e) { diff --git a/core/src/main/java/com/rudderstack/android/sdk/core/RudderDeviceModeTransformationManager.java b/core/src/main/java/com/rudderstack/android/sdk/core/RudderDeviceModeTransformationManager.java index 7fb892e16..4df66d7ec 100644 --- a/core/src/main/java/com/rudderstack/android/sdk/core/RudderDeviceModeTransformationManager.java +++ b/core/src/main/java/com/rudderstack/android/sdk/core/RudderDeviceModeTransformationManager.java @@ -5,11 +5,8 @@ import static com.rudderstack.android.sdk.core.RudderNetworkManager.Result; import static com.rudderstack.android.sdk.core.RudderNetworkManager.addEndPoint; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; +import com.rudderstack.android.sdk.core.gson.RudderGson; import com.rudderstack.android.sdk.core.util.MessageUploadLock; -import com.rudderstack.android.sdk.core.util.RudderContextSerializer; -import com.rudderstack.android.sdk.core.util.RudderTraitsSerializer; import java.util.ArrayList; import java.util.Collections; @@ -40,10 +37,6 @@ public class RudderDeviceModeTransformationManager { private static final String TRANSFORMATION_ENDPOINT = "transform"; private static final int MAX_RETRIES = 2; // Maximum number of retries private static final int MAX_DELAY = 1000; // Maximum delay in milliseconds - private static final Gson gson = new GsonBuilder() - .registerTypeAdapter(RudderTraits.class, new RudderTraitsSerializer()) - .registerTypeAdapter(RudderContext.class, new RudderContextSerializer()) - .create(); RudderDeviceModeTransformationManager(DBPersistentManager dbManager, RudderNetworkManager rudderNetworkManager, RudderDeviceModeManager rudderDeviceModeManager, RudderConfig config, RudderDataResidencyManager dataResidencyManager) { this.dbManager = dbManager; @@ -76,7 +69,7 @@ public void run() { } createMessageIdTransformationRequestMap(); TransformationRequest transformationRequest = createTransformationRequestPayload(); - String requestJson = gson.toJson(transformationRequest); + String requestJson = RudderGson.getInstance().toJson(transformationRequest); RudderLogger.logDebug(String.format(Locale.US, "DeviceModeTransformationManager: TransformationProcessor: Payload: %s", requestJson)); RudderLogger.logInfo(String.format(Locale.US, "DeviceModeTransformationManager: TransformationProcessor: EventCount: %d", messageIds.size())); @@ -100,7 +93,7 @@ public void run() { private void createMessageIdTransformationRequestMap() { for (int i = 0; i < messageIds.size(); i++) { - RudderMessage message = gson.fromJson(messages.get(i), RudderMessage.class); + RudderMessage message = RudderGson.getInstance().fromJson(messages.get(i), RudderMessage.class); reportMessageSubmittedMetric(message); messageIdTransformationRequestMap.put(messageIds.get(i), message); } @@ -192,7 +185,7 @@ private void handleResourceNotFound(TransformationRequest transformationRequest) private void handleSuccess(Result result) { deviceModeSleepCount = 0; try { - TransformationResponse transformationResponse = gson.fromJson(result.response, TransformationResponse.class); + TransformationResponse transformationResponse = RudderGson.getInstance().fromJson(result.response, TransformationResponse.class); incrementDmtSuccessMetric(transformationResponse); rudderDeviceModeManager.dumpTransformedEvents(transformationResponse); completeDeviceModeEventProcessing(); diff --git a/core/src/main/java/com/rudderstack/android/sdk/core/RudderMessage.java b/core/src/main/java/com/rudderstack/android/sdk/core/RudderMessage.java index 0112c2d7c..d4833a1fb 100644 --- a/core/src/main/java/com/rudderstack/android/sdk/core/RudderMessage.java +++ b/core/src/main/java/com/rudderstack/android/sdk/core/RudderMessage.java @@ -2,6 +2,7 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.annotation.VisibleForTesting; import com.google.gson.annotations.SerializedName; import com.rudderstack.android.sdk.core.util.Utils; @@ -262,4 +263,9 @@ public Map getIntegrations() { void setSession(RudderUserSession userSession) { this.context.setSession(userSession); } + + @VisibleForTesting + String getMessageId () { + return this.messageId; + } } diff --git a/core/src/main/java/com/rudderstack/android/sdk/core/RudderPreferenceManager.java b/core/src/main/java/com/rudderstack/android/sdk/core/RudderPreferenceManager.java index a67f2ed6b..073a948cd 100644 --- a/core/src/main/java/com/rudderstack/android/sdk/core/RudderPreferenceManager.java +++ b/core/src/main/java/com/rudderstack/android/sdk/core/RudderPreferenceManager.java @@ -6,7 +6,7 @@ import androidx.annotation.Nullable; -import com.google.gson.Gson; +import com.rudderstack.android.sdk.core.gson.RudderGson; import com.rudderstack.android.sdk.core.util.Utils; import java.util.Locale; @@ -119,7 +119,7 @@ void clearCurrentAnonymousIdValue() { if (traits != null) { Map traitsMap = Utils.convertToMap(traits); traitsMap.remove("anonymousId"); - saveTraits(new Gson().toJson(traitsMap)); + saveTraits(RudderGson.getInstance().toJson(traitsMap)); } } diff --git a/core/src/main/java/com/rudderstack/android/sdk/core/RudderServerConfigManager.java b/core/src/main/java/com/rudderstack/android/sdk/core/RudderServerConfigManager.java index 7092e1a8f..57cce35dd 100644 --- a/core/src/main/java/com/rudderstack/android/sdk/core/RudderServerConfigManager.java +++ b/core/src/main/java/com/rudderstack/android/sdk/core/RudderServerConfigManager.java @@ -3,7 +3,7 @@ import android.app.Application; import android.content.Context; -import com.google.gson.Gson; +import com.rudderstack.android.sdk.core.gson.RudderGson; import com.rudderstack.android.sdk.core.util.Utils; import java.io.FileInputStream; @@ -75,7 +75,7 @@ private void downloadConfig() { Result result = networkManager.sendNetworkRequest(null, requestUrl, RequestMethod.GET, false); if (result.status == NetworkResponses.SUCCESS) { try { - RudderServerConfig rudderServerConfig = new Gson().fromJson(result.response, RudderServerConfig.class); + RudderServerConfig rudderServerConfig = RudderGson.getInstance().fromJson(result.response, RudderServerConfig.class); RudderLogger.logDebug(String.format(Locale.US, "RudderServerConfigManager: downloadConfig: configJson: %s", result.response)); // save config for future use preferenceManger.updateLastUpdatedTime(); diff --git a/core/src/main/java/com/rudderstack/android/sdk/core/RudderTraits.java b/core/src/main/java/com/rudderstack/android/sdk/core/RudderTraits.java index ea260b7f5..18d9e21f0 100644 --- a/core/src/main/java/com/rudderstack/android/sdk/core/RudderTraits.java +++ b/core/src/main/java/com/rudderstack/android/sdk/core/RudderTraits.java @@ -2,8 +2,8 @@ import android.app.Application; -import com.google.gson.Gson; import com.google.gson.annotations.SerializedName; +import com.rudderstack.android.sdk.core.gson.RudderGson; import com.rudderstack.android.sdk.core.util.Utils; import java.util.Date; @@ -84,7 +84,7 @@ public static String getAnonymousId(Map traitsMap) { */ public static String getAddress(Map traitsMap) { if (traitsMap != null & traitsMap.containsKey(ADDRESS_KEY)) - return new Gson().toJson(traitsMap.get(ADDRESS_KEY)); + return RudderGson.getInstance().toJson(traitsMap.get(ADDRESS_KEY)); return null; } @@ -672,7 +672,7 @@ public Address putStreet(String street) { * @return address Address */ public static Address fromString(String address) { - return new Gson().fromJson(address, Address.class); + return RudderGson.getInstance().fromJson(address, Address.class); } } diff --git a/core/src/main/java/com/rudderstack/android/sdk/core/TransformationResponseDeserializer.java b/core/src/main/java/com/rudderstack/android/sdk/core/TransformationResponseDeserializer.java index 0745e0f6b..fb4fa42fa 100644 --- a/core/src/main/java/com/rudderstack/android/sdk/core/TransformationResponseDeserializer.java +++ b/core/src/main/java/com/rudderstack/android/sdk/core/TransformationResponseDeserializer.java @@ -1,8 +1,12 @@ package com.rudderstack.android.sdk.core; -import static com.rudderstack.android.sdk.core.RudderDeviceModeManager.gson; - -import com.google.gson.*; +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonDeserializer; +import com.google.gson.JsonObject; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonParseException; +import com.rudderstack.android.sdk.core.gson.RudderGson; import java.lang.reflect.Type; import java.util.ArrayList; @@ -31,7 +35,7 @@ public TransformationResponse deserialize(JsonElement json, Type typeOfT, JsonDe JsonObject eventObject = payloadObject.getAsJsonObject("event"); if (eventObject.size() > 0) { try { - message = gson.fromJson(eventObject, RudderMessage.class); + message = RudderGson.getInstance().fromJson(eventObject, RudderMessage.class); } catch (Exception e) { ReportManager.reportError(e); RudderLogger.logError(String.format("TransformationResponseDeserializer: Error while parsing event object for the destinationId: %s, and error: %s", id, e)); diff --git a/core/src/main/java/com/rudderstack/android/sdk/core/ecomm/events/CartViewedEvent.java b/core/src/main/java/com/rudderstack/android/sdk/core/ecomm/events/CartViewedEvent.java index 9f53698e2..adf86ab4a 100644 --- a/core/src/main/java/com/rudderstack/android/sdk/core/ecomm/events/CartViewedEvent.java +++ b/core/src/main/java/com/rudderstack/android/sdk/core/ecomm/events/CartViewedEvent.java @@ -1,10 +1,10 @@ package com.rudderstack.android.sdk.core.ecomm.events; -import com.google.gson.Gson; import com.rudderstack.android.sdk.core.RudderProperty; import com.rudderstack.android.sdk.core.ecomm.ECommerceCart; import com.rudderstack.android.sdk.core.ecomm.ECommerceEvents; import com.rudderstack.android.sdk.core.ecomm.ECommercePropertyBuilder; +import com.rudderstack.android.sdk.core.gson.RudderGson; import com.rudderstack.android.sdk.core.util.Utils; public class CartViewedEvent extends ECommercePropertyBuilder { @@ -28,7 +28,7 @@ public String event() { @Override public RudderProperty properties() { RudderProperty property = new RudderProperty(); - property.putValue(Utils.convertToMap(new Gson().toJson(this.cart))); + property.putValue(Utils.convertToMap(RudderGson.getInstance().toJson(this.cart))); return property; } } diff --git a/core/src/main/java/com/rudderstack/android/sdk/core/ecomm/events/CheckoutStartedEvent.java b/core/src/main/java/com/rudderstack/android/sdk/core/ecomm/events/CheckoutStartedEvent.java index fc92b2c60..3e460859f 100644 --- a/core/src/main/java/com/rudderstack/android/sdk/core/ecomm/events/CheckoutStartedEvent.java +++ b/core/src/main/java/com/rudderstack/android/sdk/core/ecomm/events/CheckoutStartedEvent.java @@ -1,10 +1,10 @@ package com.rudderstack.android.sdk.core.ecomm.events; -import com.google.gson.Gson; import com.rudderstack.android.sdk.core.RudderProperty; import com.rudderstack.android.sdk.core.ecomm.ECommerceEvents; import com.rudderstack.android.sdk.core.ecomm.ECommerceOrder; import com.rudderstack.android.sdk.core.ecomm.ECommercePropertyBuilder; +import com.rudderstack.android.sdk.core.gson.RudderGson; import com.rudderstack.android.sdk.core.util.Utils; public class CheckoutStartedEvent extends ECommercePropertyBuilder { @@ -23,7 +23,7 @@ public String event() { public RudderProperty properties() { RudderProperty property = new RudderProperty(); if (this.order != null) { - property.putValue(Utils.convertToMap(new Gson().toJson(this.order))); + property.putValue(Utils.convertToMap(RudderGson.getInstance().toJson(this.order))); } return property; } diff --git a/core/src/main/java/com/rudderstack/android/sdk/core/ecomm/events/CheckoutStepCompletedEvent.java b/core/src/main/java/com/rudderstack/android/sdk/core/ecomm/events/CheckoutStepCompletedEvent.java index 08d8b4006..390427946 100644 --- a/core/src/main/java/com/rudderstack/android/sdk/core/ecomm/events/CheckoutStepCompletedEvent.java +++ b/core/src/main/java/com/rudderstack/android/sdk/core/ecomm/events/CheckoutStepCompletedEvent.java @@ -1,10 +1,10 @@ package com.rudderstack.android.sdk.core.ecomm.events; -import com.google.gson.Gson; import com.rudderstack.android.sdk.core.RudderProperty; import com.rudderstack.android.sdk.core.ecomm.ECommerceCheckout; import com.rudderstack.android.sdk.core.ecomm.ECommerceEvents; import com.rudderstack.android.sdk.core.ecomm.ECommercePropertyBuilder; +import com.rudderstack.android.sdk.core.gson.RudderGson; import com.rudderstack.android.sdk.core.util.Utils; public class CheckoutStepCompletedEvent extends ECommercePropertyBuilder { @@ -29,7 +29,7 @@ public String event() { public RudderProperty properties() { RudderProperty property = new RudderProperty(); if (this.checkout != null) { - property.putValue(Utils.convertToMap(new Gson().toJson(this.checkout))); + property.putValue(Utils.convertToMap(RudderGson.getInstance().toJson(this.checkout))); } return property; } diff --git a/core/src/main/java/com/rudderstack/android/sdk/core/ecomm/events/CheckoutStepViewedEvent.java b/core/src/main/java/com/rudderstack/android/sdk/core/ecomm/events/CheckoutStepViewedEvent.java index 01bc5660f..49e391121 100644 --- a/core/src/main/java/com/rudderstack/android/sdk/core/ecomm/events/CheckoutStepViewedEvent.java +++ b/core/src/main/java/com/rudderstack/android/sdk/core/ecomm/events/CheckoutStepViewedEvent.java @@ -1,10 +1,10 @@ package com.rudderstack.android.sdk.core.ecomm.events; -import com.google.gson.Gson; import com.rudderstack.android.sdk.core.RudderProperty; import com.rudderstack.android.sdk.core.ecomm.ECommerceCheckout; import com.rudderstack.android.sdk.core.ecomm.ECommerceEvents; import com.rudderstack.android.sdk.core.ecomm.ECommercePropertyBuilder; +import com.rudderstack.android.sdk.core.gson.RudderGson; import com.rudderstack.android.sdk.core.util.Utils; public class CheckoutStepViewedEvent extends ECommercePropertyBuilder { @@ -29,7 +29,7 @@ public String event() { public RudderProperty properties() { RudderProperty property = new RudderProperty(); if (this.checkout != null) { - property.putValue(Utils.convertToMap(new Gson().toJson(this.checkout))); + property.putValue(Utils.convertToMap(RudderGson.getInstance().toJson(this.checkout))); } return property; } diff --git a/core/src/main/java/com/rudderstack/android/sdk/core/ecomm/events/OrderCancelledEvent.java b/core/src/main/java/com/rudderstack/android/sdk/core/ecomm/events/OrderCancelledEvent.java index 234369172..07027f681 100644 --- a/core/src/main/java/com/rudderstack/android/sdk/core/ecomm/events/OrderCancelledEvent.java +++ b/core/src/main/java/com/rudderstack/android/sdk/core/ecomm/events/OrderCancelledEvent.java @@ -1,10 +1,10 @@ package com.rudderstack.android.sdk.core.ecomm.events; -import com.google.gson.Gson; import com.rudderstack.android.sdk.core.RudderProperty; import com.rudderstack.android.sdk.core.ecomm.ECommerceEvents; import com.rudderstack.android.sdk.core.ecomm.ECommerceOrder; import com.rudderstack.android.sdk.core.ecomm.ECommercePropertyBuilder; +import com.rudderstack.android.sdk.core.gson.RudderGson; import com.rudderstack.android.sdk.core.util.Utils; public class OrderCancelledEvent extends ECommercePropertyBuilder { @@ -29,7 +29,7 @@ public String event() { public RudderProperty properties() { RudderProperty property = new RudderProperty(); if (this.order != null) { - property.putValue(Utils.convertToMap(new Gson().toJson(this.order))); + property.putValue(Utils.convertToMap(RudderGson.getInstance().toJson(this.order))); } return property; } diff --git a/core/src/main/java/com/rudderstack/android/sdk/core/ecomm/events/OrderCompletedEvent.java b/core/src/main/java/com/rudderstack/android/sdk/core/ecomm/events/OrderCompletedEvent.java index e9c669c04..09767e766 100644 --- a/core/src/main/java/com/rudderstack/android/sdk/core/ecomm/events/OrderCompletedEvent.java +++ b/core/src/main/java/com/rudderstack/android/sdk/core/ecomm/events/OrderCompletedEvent.java @@ -1,10 +1,10 @@ package com.rudderstack.android.sdk.core.ecomm.events; -import com.google.gson.Gson; import com.rudderstack.android.sdk.core.RudderProperty; import com.rudderstack.android.sdk.core.ecomm.ECommerceEvents; import com.rudderstack.android.sdk.core.ecomm.ECommerceOrder; import com.rudderstack.android.sdk.core.ecomm.ECommercePropertyBuilder; +import com.rudderstack.android.sdk.core.gson.RudderGson; import com.rudderstack.android.sdk.core.util.Utils; public class OrderCompletedEvent extends ECommercePropertyBuilder { @@ -29,7 +29,7 @@ public String event() { public RudderProperty properties() { RudderProperty property = new RudderProperty(); if (this.order != null) - property.putValue(Utils.convertToMap(new Gson().toJson(this.order))); + property.putValue(Utils.convertToMap(RudderGson.getInstance().toJson(this.order))); return property; } } diff --git a/core/src/main/java/com/rudderstack/android/sdk/core/ecomm/events/OrderRefundedEvent.java b/core/src/main/java/com/rudderstack/android/sdk/core/ecomm/events/OrderRefundedEvent.java index d07e8c855..cf5516c8f 100644 --- a/core/src/main/java/com/rudderstack/android/sdk/core/ecomm/events/OrderRefundedEvent.java +++ b/core/src/main/java/com/rudderstack/android/sdk/core/ecomm/events/OrderRefundedEvent.java @@ -1,12 +1,12 @@ package com.rudderstack.android.sdk.core.ecomm.events; -import com.google.gson.Gson; import com.rudderstack.android.sdk.core.RudderProperty; import com.rudderstack.android.sdk.core.ecomm.ECommerceEvents; import com.rudderstack.android.sdk.core.ecomm.ECommerceOrder; import com.rudderstack.android.sdk.core.ecomm.ECommerceParamNames; import com.rudderstack.android.sdk.core.ecomm.ECommerceProduct; import com.rudderstack.android.sdk.core.ecomm.ECommercePropertyBuilder; +import com.rudderstack.android.sdk.core.gson.RudderGson; import com.rudderstack.android.sdk.core.util.Utils; import java.util.ArrayList; @@ -69,7 +69,7 @@ public RudderProperty properties() { } } if (this.products != null && !this.products.isEmpty()) { - property.put(ECommerceParamNames.PRODUCTS, Utils.convertToList(new Gson().toJson(this.products))); + property.put(ECommerceParamNames.PRODUCTS, Utils.convertToList(RudderGson.getInstance().toJson(this.products))); } return property; } diff --git a/core/src/main/java/com/rudderstack/android/sdk/core/ecomm/events/OrderUpdatedEvent.java b/core/src/main/java/com/rudderstack/android/sdk/core/ecomm/events/OrderUpdatedEvent.java index b1b4ec92e..64129cf60 100644 --- a/core/src/main/java/com/rudderstack/android/sdk/core/ecomm/events/OrderUpdatedEvent.java +++ b/core/src/main/java/com/rudderstack/android/sdk/core/ecomm/events/OrderUpdatedEvent.java @@ -1,10 +1,10 @@ package com.rudderstack.android.sdk.core.ecomm.events; -import com.google.gson.Gson; import com.rudderstack.android.sdk.core.RudderProperty; import com.rudderstack.android.sdk.core.ecomm.ECommerceEvents; import com.rudderstack.android.sdk.core.ecomm.ECommerceOrder; import com.rudderstack.android.sdk.core.ecomm.ECommercePropertyBuilder; +import com.rudderstack.android.sdk.core.gson.RudderGson; import com.rudderstack.android.sdk.core.util.Utils; public class OrderUpdatedEvent extends ECommercePropertyBuilder { @@ -29,7 +29,7 @@ public String event() { public RudderProperty properties() { RudderProperty property = new RudderProperty(); if (this.order != null) { - property.putValue(Utils.convertToMap(new Gson().toJson(this.order))); + property.putValue(Utils.convertToMap(RudderGson.getInstance().toJson(this.order))); } return property; } diff --git a/core/src/main/java/com/rudderstack/android/sdk/core/ecomm/events/ProductAddedToCartEvent.java b/core/src/main/java/com/rudderstack/android/sdk/core/ecomm/events/ProductAddedToCartEvent.java index 87b541f31..0e2d6646b 100644 --- a/core/src/main/java/com/rudderstack/android/sdk/core/ecomm/events/ProductAddedToCartEvent.java +++ b/core/src/main/java/com/rudderstack/android/sdk/core/ecomm/events/ProductAddedToCartEvent.java @@ -1,11 +1,11 @@ package com.rudderstack.android.sdk.core.ecomm.events; -import com.google.gson.Gson; import com.rudderstack.android.sdk.core.RudderProperty; import com.rudderstack.android.sdk.core.ecomm.ECommerceEvents; import com.rudderstack.android.sdk.core.ecomm.ECommerceParamNames; import com.rudderstack.android.sdk.core.ecomm.ECommerceProduct; import com.rudderstack.android.sdk.core.ecomm.ECommercePropertyBuilder; +import com.rudderstack.android.sdk.core.gson.RudderGson; import com.rudderstack.android.sdk.core.util.Utils; public class ProductAddedToCartEvent extends ECommercePropertyBuilder { @@ -37,7 +37,7 @@ public ProductAddedToCartEvent withProductBuilder(ECommerceProduct.Builder build public RudderProperty properties() { RudderProperty property = new RudderProperty(); if (this.product != null) { - property.putValue(Utils.convertToMap(new Gson().toJson(this.product))); + property.putValue(Utils.convertToMap(RudderGson.getInstance().toJson(this.product))); } if (this.cartId != null) { property.put(ECommerceParamNames.CART_ID, this.cartId); diff --git a/core/src/main/java/com/rudderstack/android/sdk/core/ecomm/events/ProductAddedToWishListEvent.java b/core/src/main/java/com/rudderstack/android/sdk/core/ecomm/events/ProductAddedToWishListEvent.java index 2821b5be1..a8be58d63 100644 --- a/core/src/main/java/com/rudderstack/android/sdk/core/ecomm/events/ProductAddedToWishListEvent.java +++ b/core/src/main/java/com/rudderstack/android/sdk/core/ecomm/events/ProductAddedToWishListEvent.java @@ -1,12 +1,12 @@ package com.rudderstack.android.sdk.core.ecomm.events; -import com.google.gson.Gson; import com.rudderstack.android.sdk.core.RudderProperty; import com.rudderstack.android.sdk.core.ecomm.ECommerceEvents; import com.rudderstack.android.sdk.core.ecomm.ECommerceParamNames; import com.rudderstack.android.sdk.core.ecomm.ECommerceProduct; import com.rudderstack.android.sdk.core.ecomm.ECommercePropertyBuilder; import com.rudderstack.android.sdk.core.ecomm.ECommerceWishList; +import com.rudderstack.android.sdk.core.gson.RudderGson; import com.rudderstack.android.sdk.core.util.Utils; public class ProductAddedToWishListEvent extends ECommercePropertyBuilder { @@ -42,7 +42,7 @@ public RudderProperty properties() { property.put(ECommerceParamNames.WISHLIST_NAME, this.wishList.getWishListName()); } if (this.product != null) { - property.putValue(Utils.convertToMap(new Gson().toJson(this.product))); + property.putValue(Utils.convertToMap(RudderGson.getInstance().toJson(this.product))); } return property; } diff --git a/core/src/main/java/com/rudderstack/android/sdk/core/ecomm/events/ProductClickedEvent.java b/core/src/main/java/com/rudderstack/android/sdk/core/ecomm/events/ProductClickedEvent.java index 9f75215be..ba1fe4484 100644 --- a/core/src/main/java/com/rudderstack/android/sdk/core/ecomm/events/ProductClickedEvent.java +++ b/core/src/main/java/com/rudderstack/android/sdk/core/ecomm/events/ProductClickedEvent.java @@ -1,10 +1,10 @@ package com.rudderstack.android.sdk.core.ecomm.events; -import com.google.gson.Gson; import com.rudderstack.android.sdk.core.RudderProperty; import com.rudderstack.android.sdk.core.ecomm.ECommerceEvents; import com.rudderstack.android.sdk.core.ecomm.ECommerceProduct; import com.rudderstack.android.sdk.core.ecomm.ECommercePropertyBuilder; +import com.rudderstack.android.sdk.core.gson.RudderGson; import com.rudderstack.android.sdk.core.util.Utils; public class ProductClickedEvent extends ECommercePropertyBuilder { @@ -29,7 +29,7 @@ public String event() { public RudderProperty properties() { RudderProperty property = new RudderProperty(); if (this.product != null) { - property.putValue(Utils.convertToMap(new Gson().toJson(this.product))); + property.putValue(Utils.convertToMap(RudderGson.getInstance().toJson(this.product))); } return property; } diff --git a/core/src/main/java/com/rudderstack/android/sdk/core/ecomm/events/ProductListFilteredEvent.java b/core/src/main/java/com/rudderstack/android/sdk/core/ecomm/events/ProductListFilteredEvent.java index 72a2a7ee5..6a695f5ef 100644 --- a/core/src/main/java/com/rudderstack/android/sdk/core/ecomm/events/ProductListFilteredEvent.java +++ b/core/src/main/java/com/rudderstack/android/sdk/core/ecomm/events/ProductListFilteredEvent.java @@ -2,7 +2,6 @@ import android.text.TextUtils; -import com.google.gson.Gson; import com.rudderstack.android.sdk.core.RudderProperty; import com.rudderstack.android.sdk.core.ecomm.ECommerceEvents; import com.rudderstack.android.sdk.core.ecomm.ECommerceFilter; @@ -10,6 +9,7 @@ import com.rudderstack.android.sdk.core.ecomm.ECommerceProduct; import com.rudderstack.android.sdk.core.ecomm.ECommercePropertyBuilder; import com.rudderstack.android.sdk.core.ecomm.ECommerceSort; +import com.rudderstack.android.sdk.core.gson.RudderGson; import com.rudderstack.android.sdk.core.util.Utils; import java.util.ArrayList; @@ -172,13 +172,13 @@ public RudderProperty properties() { property.put(ECommerceParamNames.CATEGORY, this.category); } if (this.products != null && !this.products.isEmpty()) { - property.put(ECommerceParamNames.PRODUCTS, Utils.convertToList(new Gson().toJson(this.products))); + property.put(ECommerceParamNames.PRODUCTS, Utils.convertToList(RudderGson.getInstance().toJson(this.products))); } if (this.sorts != null && !this.sorts.isEmpty()) { - property.put(ECommerceParamNames.SORTS, Utils.convertToList(new Gson().toJson(this.sorts))); + property.put(ECommerceParamNames.SORTS, Utils.convertToList(RudderGson.getInstance().toJson(this.sorts))); } if (this.filters != null && !this.filters.isEmpty()) { - property.put(ECommerceParamNames.FILTERS, Utils.convertToList(new Gson().toJson(this.filters))); + property.put(ECommerceParamNames.FILTERS, Utils.convertToList(RudderGson.getInstance().toJson(this.filters))); } return property; diff --git a/core/src/main/java/com/rudderstack/android/sdk/core/ecomm/events/ProductListViewedEvent.java b/core/src/main/java/com/rudderstack/android/sdk/core/ecomm/events/ProductListViewedEvent.java index 61e07ae10..f12176522 100644 --- a/core/src/main/java/com/rudderstack/android/sdk/core/ecomm/events/ProductListViewedEvent.java +++ b/core/src/main/java/com/rudderstack/android/sdk/core/ecomm/events/ProductListViewedEvent.java @@ -2,12 +2,12 @@ import android.text.TextUtils; -import com.google.gson.Gson; import com.rudderstack.android.sdk.core.RudderProperty; import com.rudderstack.android.sdk.core.ecomm.ECommerceEvents; import com.rudderstack.android.sdk.core.ecomm.ECommerceParamNames; import com.rudderstack.android.sdk.core.ecomm.ECommerceProduct; import com.rudderstack.android.sdk.core.ecomm.ECommercePropertyBuilder; +import com.rudderstack.android.sdk.core.gson.RudderGson; import com.rudderstack.android.sdk.core.util.Utils; import java.util.ArrayList; @@ -70,7 +70,7 @@ public RudderProperty properties() { property.put(ECommerceParamNames.CATEGORY, this.category); } if (this.products != null && !this.products.isEmpty()) { - property.put(ECommerceParamNames.PRODUCTS, Utils.convertToList(new Gson().toJson(this.products))); + property.put(ECommerceParamNames.PRODUCTS, Utils.convertToList(RudderGson.getInstance().toJson(this.products))); } return property; } diff --git a/core/src/main/java/com/rudderstack/android/sdk/core/ecomm/events/ProductRemovedEvent.java b/core/src/main/java/com/rudderstack/android/sdk/core/ecomm/events/ProductRemovedEvent.java index 1aa2d46c6..c37e967f9 100644 --- a/core/src/main/java/com/rudderstack/android/sdk/core/ecomm/events/ProductRemovedEvent.java +++ b/core/src/main/java/com/rudderstack/android/sdk/core/ecomm/events/ProductRemovedEvent.java @@ -1,10 +1,10 @@ package com.rudderstack.android.sdk.core.ecomm.events; -import com.google.gson.Gson; import com.rudderstack.android.sdk.core.RudderProperty; import com.rudderstack.android.sdk.core.ecomm.ECommerceEvents; import com.rudderstack.android.sdk.core.ecomm.ECommerceProduct; import com.rudderstack.android.sdk.core.ecomm.ECommercePropertyBuilder; +import com.rudderstack.android.sdk.core.gson.RudderGson; import com.rudderstack.android.sdk.core.util.Utils; public class ProductRemovedEvent extends ECommercePropertyBuilder { @@ -29,7 +29,7 @@ public String event() { public RudderProperty properties() { RudderProperty property = new RudderProperty(); if (this.product != null) { - property.putValue(Utils.convertToMap(new Gson().toJson(this.product))); + property.putValue(Utils.convertToMap(RudderGson.getInstance().toJson(this.product))); } return property; } diff --git a/core/src/main/java/com/rudderstack/android/sdk/core/ecomm/events/ProductRemovedFromWishListEvent.java b/core/src/main/java/com/rudderstack/android/sdk/core/ecomm/events/ProductRemovedFromWishListEvent.java index 41877e603..992cb5429 100644 --- a/core/src/main/java/com/rudderstack/android/sdk/core/ecomm/events/ProductRemovedFromWishListEvent.java +++ b/core/src/main/java/com/rudderstack/android/sdk/core/ecomm/events/ProductRemovedFromWishListEvent.java @@ -1,12 +1,12 @@ package com.rudderstack.android.sdk.core.ecomm.events; -import com.google.gson.Gson; import com.rudderstack.android.sdk.core.RudderProperty; import com.rudderstack.android.sdk.core.ecomm.ECommerceEvents; import com.rudderstack.android.sdk.core.ecomm.ECommerceParamNames; import com.rudderstack.android.sdk.core.ecomm.ECommerceProduct; import com.rudderstack.android.sdk.core.ecomm.ECommercePropertyBuilder; import com.rudderstack.android.sdk.core.ecomm.ECommerceWishList; +import com.rudderstack.android.sdk.core.gson.RudderGson; import com.rudderstack.android.sdk.core.util.Utils; public class ProductRemovedFromWishListEvent extends ECommercePropertyBuilder { @@ -42,7 +42,7 @@ public RudderProperty properties() { property.put(ECommerceParamNames.WISHLIST_NAME, this.wishList.getWishListName()); } if (this.product != null) { - property.putValue(Utils.convertToMap(new Gson().toJson(this.product))); + property.putValue(Utils.convertToMap(RudderGson.getInstance().toJson(this.product))); } return property; } diff --git a/core/src/main/java/com/rudderstack/android/sdk/core/ecomm/events/ProductSharedEvent.java b/core/src/main/java/com/rudderstack/android/sdk/core/ecomm/events/ProductSharedEvent.java index 1e7930a45..f358daa1e 100644 --- a/core/src/main/java/com/rudderstack/android/sdk/core/ecomm/events/ProductSharedEvent.java +++ b/core/src/main/java/com/rudderstack/android/sdk/core/ecomm/events/ProductSharedEvent.java @@ -2,12 +2,12 @@ import android.text.TextUtils; -import com.google.gson.Gson; import com.rudderstack.android.sdk.core.RudderProperty; import com.rudderstack.android.sdk.core.ecomm.ECommerceEvents; import com.rudderstack.android.sdk.core.ecomm.ECommerceParamNames; import com.rudderstack.android.sdk.core.ecomm.ECommerceProduct; import com.rudderstack.android.sdk.core.ecomm.ECommercePropertyBuilder; +import com.rudderstack.android.sdk.core.gson.RudderGson; import com.rudderstack.android.sdk.core.util.Utils; public class ProductSharedEvent extends ECommercePropertyBuilder { @@ -53,7 +53,7 @@ public String event() { public RudderProperty properties() { RudderProperty property = new RudderProperty(); if (this.product != null) { - property.putValue(Utils.convertToMap(new Gson().toJson(this.product))); + property.putValue(Utils.convertToMap(RudderGson.getInstance().toJson(this.product))); } if (!TextUtils.isEmpty(this.socialChannel)) { property.put(ECommerceParamNames.SHARE_VIA, this.socialChannel); diff --git a/core/src/main/java/com/rudderstack/android/sdk/core/ecomm/events/ProductViewedEvent.java b/core/src/main/java/com/rudderstack/android/sdk/core/ecomm/events/ProductViewedEvent.java index c7dc990c1..c7a9bf323 100644 --- a/core/src/main/java/com/rudderstack/android/sdk/core/ecomm/events/ProductViewedEvent.java +++ b/core/src/main/java/com/rudderstack/android/sdk/core/ecomm/events/ProductViewedEvent.java @@ -1,10 +1,10 @@ package com.rudderstack.android.sdk.core.ecomm.events; -import com.google.gson.Gson; import com.rudderstack.android.sdk.core.RudderProperty; import com.rudderstack.android.sdk.core.ecomm.ECommerceEvents; import com.rudderstack.android.sdk.core.ecomm.ECommerceProduct; import com.rudderstack.android.sdk.core.ecomm.ECommercePropertyBuilder; +import com.rudderstack.android.sdk.core.gson.RudderGson; import com.rudderstack.android.sdk.core.util.Utils; public class ProductViewedEvent extends ECommercePropertyBuilder { @@ -29,7 +29,7 @@ public String event() { public RudderProperty properties() { RudderProperty property = new RudderProperty(); if (this.product != null) { - property.putValue(Utils.convertToMap(new Gson().toJson(this.product))); + property.putValue(Utils.convertToMap(RudderGson.getInstance().toJson(this.product))); } return property; } diff --git a/core/src/main/java/com/rudderstack/android/sdk/core/ecomm/events/PromotionClickedEvent.java b/core/src/main/java/com/rudderstack/android/sdk/core/ecomm/events/PromotionClickedEvent.java index 6f62558fd..ab794f9c4 100644 --- a/core/src/main/java/com/rudderstack/android/sdk/core/ecomm/events/PromotionClickedEvent.java +++ b/core/src/main/java/com/rudderstack/android/sdk/core/ecomm/events/PromotionClickedEvent.java @@ -1,10 +1,10 @@ package com.rudderstack.android.sdk.core.ecomm.events; -import com.google.gson.Gson; import com.rudderstack.android.sdk.core.RudderProperty; import com.rudderstack.android.sdk.core.ecomm.ECommerceEvents; import com.rudderstack.android.sdk.core.ecomm.ECommercePromotion; import com.rudderstack.android.sdk.core.ecomm.ECommercePropertyBuilder; +import com.rudderstack.android.sdk.core.gson.RudderGson; import com.rudderstack.android.sdk.core.util.Utils; public class PromotionClickedEvent extends ECommercePropertyBuilder { @@ -29,7 +29,7 @@ public String event() { public RudderProperty properties() { RudderProperty property = new RudderProperty(); if (this.promotion != null) { - property.putValue(Utils.convertToMap(new Gson().toJson(this.promotion))); + property.putValue(Utils.convertToMap(RudderGson.getInstance().toJson(this.promotion))); } return property; } diff --git a/core/src/main/java/com/rudderstack/android/sdk/core/ecomm/events/PromotionViewedEvent.java b/core/src/main/java/com/rudderstack/android/sdk/core/ecomm/events/PromotionViewedEvent.java index f59ae512f..af4158e42 100644 --- a/core/src/main/java/com/rudderstack/android/sdk/core/ecomm/events/PromotionViewedEvent.java +++ b/core/src/main/java/com/rudderstack/android/sdk/core/ecomm/events/PromotionViewedEvent.java @@ -1,10 +1,10 @@ package com.rudderstack.android.sdk.core.ecomm.events; -import com.google.gson.Gson; import com.rudderstack.android.sdk.core.RudderProperty; import com.rudderstack.android.sdk.core.ecomm.ECommerceEvents; import com.rudderstack.android.sdk.core.ecomm.ECommercePromotion; import com.rudderstack.android.sdk.core.ecomm.ECommercePropertyBuilder; +import com.rudderstack.android.sdk.core.gson.RudderGson; import com.rudderstack.android.sdk.core.util.Utils; public class PromotionViewedEvent extends ECommercePropertyBuilder { @@ -30,7 +30,7 @@ public String event() { public RudderProperty properties() { RudderProperty property = new RudderProperty(); if (this.promotion != null) { - property.putValue(Utils.convertToMap(new Gson().toJson(this.promotion))); + property.putValue(Utils.convertToMap(RudderGson.getInstance().toJson(this.promotion))); } return property; } diff --git a/core/src/main/java/com/rudderstack/android/sdk/core/ecomm/events/WishListProductAddedToCartEvent.java b/core/src/main/java/com/rudderstack/android/sdk/core/ecomm/events/WishListProductAddedToCartEvent.java index 2f88f86b1..cc71171eb 100644 --- a/core/src/main/java/com/rudderstack/android/sdk/core/ecomm/events/WishListProductAddedToCartEvent.java +++ b/core/src/main/java/com/rudderstack/android/sdk/core/ecomm/events/WishListProductAddedToCartEvent.java @@ -2,7 +2,6 @@ import android.text.TextUtils; -import com.google.gson.Gson; import com.rudderstack.android.sdk.core.RudderProperty; import com.rudderstack.android.sdk.core.ecomm.ECommerceCart; import com.rudderstack.android.sdk.core.ecomm.ECommerceEvents; @@ -10,6 +9,7 @@ import com.rudderstack.android.sdk.core.ecomm.ECommerceProduct; import com.rudderstack.android.sdk.core.ecomm.ECommercePropertyBuilder; import com.rudderstack.android.sdk.core.ecomm.ECommerceWishList; +import com.rudderstack.android.sdk.core.gson.RudderGson; import com.rudderstack.android.sdk.core.util.Utils; public class WishListProductAddedToCartEvent extends ECommercePropertyBuilder { @@ -64,7 +64,7 @@ public RudderProperty properties() { property.put(ECommerceParamNames.WISHLIST_NAME, this.wishList.getWishListName()); } if (this.product != null) { - property.putValue(Utils.convertToMap(new Gson().toJson(this.product))); + property.putValue(Utils.convertToMap(RudderGson.getInstance().toJson(this.product))); } if (!TextUtils.isEmpty(this.cartId)) { property.put(ECommerceParamNames.CART_ID, this.cartId); diff --git a/core/src/main/java/com/rudderstack/android/sdk/core/gson/RudderGson.java b/core/src/main/java/com/rudderstack/android/sdk/core/gson/RudderGson.java new file mode 100644 index 000000000..35fc4c2fe --- /dev/null +++ b/core/src/main/java/com/rudderstack/android/sdk/core/gson/RudderGson.java @@ -0,0 +1,33 @@ +package com.rudderstack.android.sdk.core.gson; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.rudderstack.android.sdk.core.RudderContext; +import com.rudderstack.android.sdk.core.RudderTraits; +import com.rudderstack.android.sdk.core.gson.gsonadapters.RudderContextTypeAdapter; +import com.rudderstack.android.sdk.core.gson.gsonadapters.RudderJSONArrayTypeAdapter; +import com.rudderstack.android.sdk.core.gson.gsonadapters.RudderJSONObjectTypeAdapter; +import com.rudderstack.android.sdk.core.gson.gsonadapters.RudderTraitsTypeAdapter; + +import org.json.JSONArray; +import org.json.JSONObject; + +public class RudderGson { + private static Gson instance; + + private RudderGson() { + // private constructor to prevent instantiation + } + + public static Gson getInstance() { + if (instance == null) { + instance = new GsonBuilder() + .registerTypeAdapter(RudderTraits.class, new RudderTraitsTypeAdapter()) + .registerTypeAdapter(RudderContext.class, new RudderContextTypeAdapter()) + .registerTypeAdapter(JSONObject.class, new RudderJSONObjectTypeAdapter()) + .registerTypeAdapter(JSONArray.class, new RudderJSONArrayTypeAdapter()) + .create(); + } + return instance; + } +} diff --git a/core/src/main/java/com/rudderstack/android/sdk/core/util/RudderContextSerializer.java b/core/src/main/java/com/rudderstack/android/sdk/core/gson/gsonadapters/RudderContextTypeAdapter.java similarity index 91% rename from core/src/main/java/com/rudderstack/android/sdk/core/util/RudderContextSerializer.java rename to core/src/main/java/com/rudderstack/android/sdk/core/gson/gsonadapters/RudderContextTypeAdapter.java index c5c20b41a..aabd41dab 100644 --- a/core/src/main/java/com/rudderstack/android/sdk/core/util/RudderContextSerializer.java +++ b/core/src/main/java/com/rudderstack/android/sdk/core/gson/gsonadapters/RudderContextTypeAdapter.java @@ -1,4 +1,4 @@ -package com.rudderstack.android.sdk.core.util; +package com.rudderstack.android.sdk.core.gson.gsonadapters; import com.google.gson.Gson; import com.google.gson.JsonElement; @@ -11,14 +11,14 @@ import java.lang.reflect.Type; import java.util.Map; -public class RudderContextSerializer implements JsonSerializer { +public class RudderContextTypeAdapter implements JsonSerializer { @Override public JsonElement serialize(RudderContext rudderContext, Type typeOfSrc, JsonSerializationContext context) { try { - Gson gson = new Gson(); JsonObject outputContext = new JsonObject(); + Gson gson = new Gson(); JsonObject inputContext = (JsonObject) gson.toJsonTree(rudderContext); for (Map.Entry entry : inputContext.entrySet()) { if (entry.getKey().equals("customContextMap")) { diff --git a/core/src/main/java/com/rudderstack/android/sdk/core/gson/gsonadapters/RudderJSONArrayTypeAdapter.java b/core/src/main/java/com/rudderstack/android/sdk/core/gson/gsonadapters/RudderJSONArrayTypeAdapter.java new file mode 100644 index 000000000..ccae3c604 --- /dev/null +++ b/core/src/main/java/com/rudderstack/android/sdk/core/gson/gsonadapters/RudderJSONArrayTypeAdapter.java @@ -0,0 +1,44 @@ +package com.rudderstack.android.sdk.core.gson.gsonadapters; + +import com.google.gson.JsonArray; +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonDeserializer; +import com.google.gson.JsonElement; +import com.google.gson.JsonParseException; +import com.google.gson.JsonSerializationContext; +import com.google.gson.JsonSerializer; + +import org.json.JSONArray; +import org.json.JSONException; + +import java.lang.reflect.Type; + + +public class RudderJSONArrayTypeAdapter implements JsonSerializer, JsonDeserializer { + + @Override + public JsonElement serialize(JSONArray src, Type typeOfSrc, JsonSerializationContext context) { + if (src == null) { + return null; + } + JsonArray jsonArray = new JsonArray(); + for (int i = 0; i < src.length(); i++) { + Object object = src.opt(i); + JsonElement jsonElement = context.serialize(object, object.getClass()); + jsonArray.add(jsonElement); + } + return jsonArray; + } + + @Override + public JSONArray deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { + if (json == null) { + return null; + } + try { + return new JSONArray(json.toString()); + } catch (JSONException e) { + throw new JsonParseException(e); + } + } +} \ No newline at end of file diff --git a/core/src/main/java/com/rudderstack/android/sdk/core/gson/gsonadapters/RudderJSONObjectTypeAdapter.java b/core/src/main/java/com/rudderstack/android/sdk/core/gson/gsonadapters/RudderJSONObjectTypeAdapter.java new file mode 100644 index 000000000..ab7be8718 --- /dev/null +++ b/core/src/main/java/com/rudderstack/android/sdk/core/gson/gsonadapters/RudderJSONObjectTypeAdapter.java @@ -0,0 +1,49 @@ +package com.rudderstack.android.sdk.core.gson.gsonadapters; + +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonDeserializer; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParseException; +import com.google.gson.JsonSerializationContext; +import com.google.gson.JsonSerializer; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.lang.reflect.Type; +import java.util.Iterator; + +public class RudderJSONObjectTypeAdapter implements JsonSerializer, JsonDeserializer { + + @Override + public JsonElement serialize(JSONObject src, Type typeOfSrc, JsonSerializationContext context) { + if (src == null) { + return null; + } + + JsonObject jsonObject = new JsonObject(); + Iterator keys = src.keys(); + while (keys.hasNext()) { + String key = keys.next(); + Object value = src.opt(key); + + JsonElement jsonElement = context.serialize(value, value.getClass()); + jsonObject.add(key, jsonElement); + } + return jsonObject; + } + + @Override + public JSONObject deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { + if (json == null) { + return null; + } + try { + return new JSONObject(json.toString()); + } catch (JSONException e) { + throw new JsonParseException(e); + } + } +} + diff --git a/core/src/main/java/com/rudderstack/android/sdk/core/util/RudderTraitsSerializer.java b/core/src/main/java/com/rudderstack/android/sdk/core/gson/gsonadapters/RudderTraitsTypeAdapter.java similarity index 91% rename from core/src/main/java/com/rudderstack/android/sdk/core/util/RudderTraitsSerializer.java rename to core/src/main/java/com/rudderstack/android/sdk/core/gson/gsonadapters/RudderTraitsTypeAdapter.java index 77824c805..465bd9158 100644 --- a/core/src/main/java/com/rudderstack/android/sdk/core/util/RudderTraitsSerializer.java +++ b/core/src/main/java/com/rudderstack/android/sdk/core/gson/gsonadapters/RudderTraitsTypeAdapter.java @@ -1,4 +1,4 @@ -package com.rudderstack.android.sdk.core.util; +package com.rudderstack.android.sdk.core.gson.gsonadapters; import com.google.gson.Gson; import com.google.gson.JsonElement; @@ -11,14 +11,14 @@ import java.lang.reflect.Type; import java.util.Map; -public class RudderTraitsSerializer implements JsonSerializer { +public class RudderTraitsTypeAdapter implements JsonSerializer { @Override public JsonElement serialize(RudderTraits traits, Type typeOfSrc, JsonSerializationContext context) { try { - Gson gson = new Gson(); JsonObject outputTraits = new JsonObject(); + Gson gson = new Gson(); JsonObject inputTraits = (JsonObject) gson.toJsonTree(traits); for (Map.Entry entry : inputTraits.entrySet()) { if (entry.getKey().equals("extras")) { diff --git a/core/src/main/java/com/rudderstack/android/sdk/core/util/Utils.java b/core/src/main/java/com/rudderstack/android/sdk/core/util/Utils.java index 47e2fadad..554239134 100644 --- a/core/src/main/java/com/rudderstack/android/sdk/core/util/Utils.java +++ b/core/src/main/java/com/rudderstack/android/sdk/core/util/Utils.java @@ -5,21 +5,17 @@ import android.app.UiModeManager; import android.content.Context; import android.content.Intent; -import android.content.pm.PackageInfo; -import android.content.pm.PackageManager; import android.content.res.Configuration; import android.net.ParseException; import android.net.Uri; import android.os.BadParcelableException; import android.os.Build; -import android.os.Message; import android.text.TextUtils; -import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; import com.rudderstack.android.sdk.core.ReportManager; import com.rudderstack.android.sdk.core.RudderLogger; -import com.rudderstack.android.sdk.core.RudderProperty; +import com.rudderstack.android.sdk.core.gson.RudderGson; import java.io.File; import java.io.UnsupportedEncodingException; @@ -31,9 +27,7 @@ import java.util.Locale; import java.util.Map; import java.util.TimeZone; -import java.util.UUID; import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicBoolean; import static android.content.Context.UI_MODE_SERVICE; import static android.provider.Settings.Secure.ANDROID_ID; @@ -97,12 +91,13 @@ public static String getDeviceId(Application application) { } public static Map convertToMap(String json) { - return new Gson().fromJson(json, new TypeToken>() { - }.getType()); + return RudderGson.getInstance().fromJson(json, new TypeToken>() { + }.getType() + ); } public static List> convertToList(String json) { - return new Gson().fromJson(json, new TypeToken>>() { + return RudderGson.getInstance().fromJson(json, new TypeToken>>() { }.getType()); } diff --git a/core/src/test/java/com/rudderstack/android/sdk/core/DBPersistentManagerTest.java b/core/src/test/java/com/rudderstack/android/sdk/core/DBPersistentManagerTest.java index fdb50677e..bd9a239a7 100644 --- a/core/src/test/java/com/rudderstack/android/sdk/core/DBPersistentManagerTest.java +++ b/core/src/test/java/com/rudderstack/android/sdk/core/DBPersistentManagerTest.java @@ -6,12 +6,8 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mockito; -import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; import org.powermock.api.mockito.PowerMockito; -import org.powermock.core.classloader.annotations.PowerMockIgnore; -import org.powermock.modules.junit4.PowerMockRunner; -import org.powermock.modules.junit4.PowerMockRunnerDelegate; import org.powermock.reflect.Whitebox; import org.robolectric.RobolectricTestRunner; import org.robolectric.annotation.Config; @@ -21,12 +17,11 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; -import static java.util.concurrent.TimeUnit.MINUTES; import static java.util.concurrent.TimeUnit.SECONDS; import android.os.Build; import android.os.Message; -import static com.rudderstack.android.sdk.core.DBPersistentManager.UPDATED_COL; + import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.allOf; import static org.hamcrest.Matchers.equalTo; @@ -37,18 +32,14 @@ import static java.lang.Thread.sleep; import android.app.Application; -import android.os.Build; import androidx.test.core.app.ApplicationProvider; -import androidx.test.runner.AndroidJUnit4; -import com.google.common.reflect.TypeToken; import com.google.gson.Gson; import com.google.gson.GsonBuilder; -import com.rudderstack.android.sdk.core.util.RudderContextSerializer; -import com.rudderstack.android.sdk.core.util.RudderTraitsSerializer; import com.google.common.collect.ImmutableList; +import com.rudderstack.android.sdk.core.gson.RudderGson; import java.util.ArrayList; import java.util.LinkedList; @@ -63,10 +54,6 @@ public class DBPersistentManagerTest { DBPersistentManager dbPersistentManager; private final List messages = new ArrayList(ImmutableList.of("{\"message\":\"m-1\"}", "{\"message\":\"m-2\"}", "{\"message\":\"m-3\"}", "{\"message\":\"m-4\"}", "{\"message\":\"m-5\"}", "{\"message\":\"m-6\"}", "{\"message\":\"m-7\"}", "{\"message\":\"m-8\"}", "{\"message\":\"m-9\"}")); - private final Gson gson = new GsonBuilder() - .registerTypeAdapter(RudderTraits.class, new RudderTraitsSerializer()) - .registerTypeAdapter(RudderContext.class, new RudderContextSerializer()) - .create(); private static final String MESSAGE_1 = " {\n" + " \"event\": \"mess-1\",\n" + " \"messageId\": \"e-1\",\n" + @@ -228,7 +215,7 @@ private List parse(List messageJsons) { List messages = new ArrayList<>(); for (String mJson : messageJsons) { - messages.add(gson.fromJson(mJson, RudderMessage.class)); + messages.add(RudderGson.getInstance().fromJson(mJson, RudderMessage.class)); } return messages; } diff --git a/core/src/test/java/com/rudderstack/android/sdk/core/EventRepositoryTest.java b/core/src/test/java/com/rudderstack/android/sdk/core/EventRepositoryTest.java index 424aebf71..3c95245eb 100644 --- a/core/src/test/java/com/rudderstack/android/sdk/core/EventRepositoryTest.java +++ b/core/src/test/java/com/rudderstack/android/sdk/core/EventRepositoryTest.java @@ -4,6 +4,7 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.allOf; import static org.hamcrest.Matchers.hasEntry; +import static org.hamcrest.Matchers.is; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyList; import static org.mockito.ArgumentMatchers.anyString; @@ -15,6 +16,9 @@ import com.rudderstack.android.sdk.core.util.Utils; import org.hamcrest.Matchers; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -30,6 +34,7 @@ import org.powermock.modules.junit4.PowerMockRunner; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.concurrent.Callable; import java.util.concurrent.atomic.AtomicInteger; @@ -146,14 +151,14 @@ public void flush() throws Exception { // arg2.capture(), // arg3.capture() // ); - assertThat(result, Matchers.is(true)); + assertThat(result, is(true)); System.out.println(arg1.getValue()); assertThat(arg1.getValue().replace(" ", ""), - Matchers.is(expectedPayload.replace("\n", "").replace(" ", ""))); + is(expectedPayload.replace("\n", "").replace(" ", ""))); System.out.println(arg2.getValue()); - assertThat(arg2.getValue().replace(" ", ""), Matchers.is("api.rudderstack.com/v1/batch")); + assertThat(arg2.getValue().replace(" ", ""), is("api.rudderstack.com/v1/batch")); System.out.println(arg3.getValue()); - assertThat(arg3.getValue(), Matchers.is(RudderNetworkManager.RequestMethod.POST)); + assertThat(arg3.getValue(), is(RudderNetworkManager.RequestMethod.POST)); } private int dbFetchCalled = 0; @@ -240,5 +245,120 @@ public void applyRudderOptionsToMessageIntegrations() { hasEntry("All", true) )); } + + @Test + public void testGetEventJson() throws JSONException { + EventRepository repo = new EventRepository(); + HashMap jsonData = new HashMap(); + jsonData.put("pinId", 2351636); + jsonData.put("userLocationLongitude", 12.516869940636775); + jsonData.put("userLocationLatitude", 55.661663449562205); + jsonData.put("userDirection", 12.311176); + jsonData.put("userSpeed", 13.888889); + jsonData.put("locationHorizontalAccuracy", 3.813398); + jsonData.put("locationVerticalAccuracy", 0.0); + jsonData.put("speedAccuracy", 0.0); + jsonData.put("directionAccuracy", 0.0); + JSONArray locationsBefore = new JSONArray(); + locationsBefore.put(new JSONObject().put("latitude", 55.66132122924984).put("longitude", 12.51671169784383)); + locationsBefore.put(new JSONObject().put("latitude", 55.661428115890374).put("longitude", 12.51677390468785)); + locationsBefore.put(new JSONObject().put("latitude", 55.661663449562205).put("longitude", 12.516869940636775)); + jsonData.put("locationsBefore", locationsBefore); + JSONArray locationsAfter = new JSONArray(); + locationsAfter.put(new JSONObject().put("latitude", 55.66190443423447).put("longitude", 12.516850445696493)); + locationsAfter.put(new JSONObject().put("latitude", 55.66214021085126).put("longitude", 12.516731010346978)); + locationsAfter.put(new JSONObject().put("latitude", 55.66237844832189).put("longitude", 12.516618424859859)); + jsonData.put("locationsAfter", locationsAfter); + JSONArray speedsBefore = new JSONArray(); + speedsBefore.put(new JSONObject().put("speed", 0)); + speedsBefore.put(new JSONObject().put("speed", 13.888889)); + speedsBefore.put(new JSONObject().put("speed", 13.888889)); + jsonData.put("speedsBefore", speedsBefore); + JSONArray speedsAfter = new JSONArray(); + speedsAfter.put(new JSONObject().put("speed", 13.888889)); + speedsAfter.put(new JSONObject().put("speed", 13.888889)); + jsonData.put("speedsAfter", speedsAfter); + jsonData.put("pinType", 1); + jsonData.put("pinSubtype", 11); + jsonData.put("pinDirection", 0.0); + jsonData.put("pinLocationLongitude", 12.507275); + jsonData.put("pinLocationLatitude", 55.672436); + jsonData.put("coDriverVersion", -1.0); + RudderMessage message = new RudderMessageBuilder().setEventName("TestEvent").setProperty(jsonData).build(); + String expectedJsonString = "{\n" + + " \"messageId\": \""+message.getMessageId()+"\",\n" + + " \"channel\": \"mobile\",\n" + + " \"context\": {},\n" + + " \"originalTimestamp\": \"2022-03-14T06:46:41.365Z\",\n" + + " \"event\": \"TestEvent\",\n" + + " \"properties\": {\n" + + " \"pinLocationLongitude\": 12.507275,\n" + + " \"userDirection\": 12.311176,\n" + + " \"locationHorizontalAccuracy\": 3.813398,\n" + + " \"pinId\": 2351636,\n" + + " \"pinDirection\": 0.0,\n" + + " \"coDriverVersion\": -1.0,\n" + + " \"userLocationLatitude\": 55.661663449562205,\n" + + " \"userSpeed\": 13.888889,\n" + + " \"locationsBefore\": [\n" + + " {\n" + + " \"latitude\": 55.66132122924984,\n" + + " \"longitude\": 12.51671169784383\n" + + " },\n" + + " {\n" + + " \"latitude\": 55.661428115890374,\n" + + " \"longitude\": 12.51677390468785\n" + + " },\n" + + " {\n" + + " \"latitude\": 55.661663449562205,\n" + + " \"longitude\": 12.516869940636775\n" + + " }\n" + + " ],\n" + + " \"speedAccuracy\": 0.0,\n" + + " \"locationVerticalAccuracy\": 0.0,\n" + + " \"pinType\": 1,\n" + + " \"speedsAfter\": [\n" + + " {\n" + + " \"speed\": 13.888889\n" + + " },\n" + + " {\n" + + " \"speed\": 13.888889\n" + + " }\n" + + " ],\n" + + " \"pinSubtype\": 11,\n" + + " \"locationsAfter\": [\n" + + " {\n" + + " \"latitude\": 55.66190443423447,\n" + + " \"longitude\": 12.516850445696493\n" + + " },\n" + + " {\n" + + " \"latitude\": 55.66214021085126,\n" + + " \"longitude\": 12.516731010346978\n" + + " },\n" + + " {\n" + + " \"latitude\": 55.66237844832189,\n" + + " \"longitude\": 12.516618424859859\n" + + " }\n" + + " ],\n" + + " \"speedsBefore\": [\n" + + " {\n" + + " \"speed\": 0\n" + + " },\n" + + " {\n" + + " \"speed\": 13.888889\n" + + " },\n" + + " {\n" + + " \"speed\": 13.888889\n" + + " }\n" + + " ],\n" + + " \"pinLocationLatitude\": 55.672436,\n" + + " \"userLocationLongitude\": 12.516869940636775,\n" + + " \"directionAccuracy\": 0.0\n" + + " },\n" + + " \"integrations\": {}\n" + + "}"; + String outputJsonString = repo.getEventJsonString(message); + assertThat("JSONObjects and JSONArray are serialized perfectly", outputJsonString , is(expectedJsonString.replace("\n", "").replace(" ", ""))); + } } diff --git a/core/src/test/java/com/rudderstack/android/sdk/core/ReflectionUtils.java b/core/src/test/java/com/rudderstack/android/sdk/core/ReflectionUtils.java index ed0ee1827..e7182e6fd 100644 --- a/core/src/test/java/com/rudderstack/android/sdk/core/ReflectionUtils.java +++ b/core/src/test/java/com/rudderstack/android/sdk/core/ReflectionUtils.java @@ -23,5 +23,11 @@ public static R getObject(T object, String fieldName) throws NoSuchFieldE field.setAccessible(true); return (R) field.get(object); } + public static void setPrivateField(Object target, String fieldName, Object value) + throws NoSuchFieldException, IllegalAccessException { + Field field = target.getClass().getDeclaredField(fieldName); + field.setAccessible(true); + field.set(target, value); + } } diff --git a/core/src/test/java/com/rudderstack/android/sdk/core/RudderGsonTest.java b/core/src/test/java/com/rudderstack/android/sdk/core/RudderGsonTest.java new file mode 100644 index 000000000..91384f8e3 --- /dev/null +++ b/core/src/test/java/com/rudderstack/android/sdk/core/RudderGsonTest.java @@ -0,0 +1,274 @@ +package com.rudderstack.android.sdk.core; + + +import static org.awaitility.Awaitility.await; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; + +import static java.util.concurrent.TimeUnit.SECONDS; + + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; +import org.junit.Test; +import org.mockito.MockedStatic; +import org.mockito.Mockito; + +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.atomic.AtomicInteger; + +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import com.rudderstack.android.sdk.core.gson.RudderGson; +import com.rudderstack.android.sdk.core.util.Utils; + +public class RudderGsonTest { + @Test + public void testRudderContextSerializationSynchronicity() { + AtomicInteger contextsSerialized = new AtomicInteger(0); + new Thread() { + @Override + public void run() { + super.run(); + for (int i = 1; i <= 1000; i++) { + RudderContext context = null; + try { + context = getRudderContext(i); + } catch (NoSuchFieldException e) { + throw new RuntimeException(e); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } + assertThat("contexts got serialized perfectly " + i, areJsonStringsEqual(RudderGson.getInstance().toJson(context), getRudderContextJsonString(i)), is(true)); + contextsSerialized.addAndGet(1); + } + } + }.start(); + new Thread() { + @Override + public void run() { + super.run(); + for (int i = 1001; i <= 2000; i++) { + RudderContext context = null; + try { + context = getRudderContext(i); + } catch (NoSuchFieldException e) { + throw new RuntimeException(e); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } + assertThat("contexts got serialized perfectly", areJsonStringsEqual(RudderGson.getInstance().toJson(context), getRudderContextJsonString(i)), is(true)); + contextsSerialized.addAndGet(1); + } + } + }.start(); + new Thread() { + @Override + public void run() { + super.run(); + for (int i = 2001; i <= 3000; i++) { + RudderContext context = null; + try { + context = getRudderContext(i); + } catch (NoSuchFieldException e) { + throw new RuntimeException(e); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } + assertThat("contexts got serialized perfectly", areJsonStringsEqual(RudderGson.getInstance().toJson(context), getRudderContextJsonString(i)), is(true)); + contextsSerialized.addAndGet(1); + } + } + }.start(); + await().atMost(60, SECONDS).until(() -> contextsSerialized.get() == 3000); + } + + private RudderContext getRudderContext(int i) throws NoSuchFieldException, IllegalAccessException { + RudderContext context = getDefaultRudderContext(); + Map customContextMap = new HashMap<>(); + Map companyContext = new HashMap<>(); + companyContext.put("name", "company" + i); + companyContext.put("city", "city" + i); + customContextMap.put("company", companyContext); + Map personContext = new HashMap<>(); + personContext.put("tier", "enterprise" + i); + customContextMap.put("person", personContext); + ReflectionUtils.setPrivateField(context, "customContextMap", customContextMap); + return context; + } + private RudderContext getDefaultRudderContext() throws NoSuchFieldException, IllegalAccessException { + RudderContext context = Mockito.mock(RudderContext.class); + RudderApp app = Mockito.mock(RudderApp.class); + ReflectionUtils.setPrivateField(app, "build", "2"); + ReflectionUtils.setPrivateField(app, "name", "rudderstack-android-sdk-desu"); + ReflectionUtils.setPrivateField(app, "nameSpace", "com.rudderstack.android.sdk.core"); + ReflectionUtils.setPrivateField(app, "version", "1.1"); + ReflectionUtils.setPrivateField(context, "app", app); + RudderLibraryInfo libraryInfo = Mockito.mock(RudderLibraryInfo.class); + ReflectionUtils.setPrivateField(libraryInfo, "name", "com.rudderstack.android.sdk.core"); + ReflectionUtils.setPrivateField(libraryInfo, "version", "1.20.1"); + ReflectionUtils.setPrivateField(context, "libraryInfo", libraryInfo); + RudderOSInfo osInfo = Mockito.mock(RudderOSInfo.class); + ReflectionUtils.setPrivateField(osInfo, "name", "Android"); + ReflectionUtils.setPrivateField(osInfo, "version", "14"); + ReflectionUtils.setPrivateField(context, "osInfo", osInfo); + RudderScreenInfo screenInfo = Mockito.mock(RudderScreenInfo.class); + ReflectionUtils.setPrivateField(screenInfo, "density", 3); + ReflectionUtils.setPrivateField(screenInfo, "height", 736); + ReflectionUtils.setPrivateField(screenInfo, "width", 414); + ReflectionUtils.setPrivateField(context, "screenInfo", screenInfo); + ReflectionUtils.setPrivateField(context, "userAgent", "Dalvik/2.1.0 (Linux; U; Android 14; sdk_gphone64_arm64 Build/UPB4.230623.005)"); + ReflectionUtils.setPrivateField(context, "locale", "en-US"); + RudderNetwork networkInfo = Mockito.mock(RudderNetwork.class); + ReflectionUtils.setPrivateField(networkInfo, "isCellularEnabled", true); + ReflectionUtils.setPrivateField(networkInfo, "isWifiEnabled", true); + ReflectionUtils.setPrivateField(networkInfo, "isBluetoothEnabled", false); + ReflectionUtils.setPrivateField(networkInfo, "carrier", "T-Mobile"); + ReflectionUtils.setPrivateField(context, "networkInfo", networkInfo); + RudderDeviceInfo deviceInfo = Mockito.mock(RudderDeviceInfo.class); + ReflectionUtils.setPrivateField(deviceInfo, "type", "Android"); + ReflectionUtils.setPrivateField(deviceInfo, "manufacturer", "Google"); + ReflectionUtils.setPrivateField(deviceInfo, "model", "sdk_gphone64_arm64"); + ReflectionUtils.setPrivateField(deviceInfo, "name", "emu64a"); + ReflectionUtils.setPrivateField(deviceInfo, "deviceId", "10f9e80f-5342-48e0-8908-1b221179895b"); + ReflectionUtils.setPrivateField(context, "deviceInfo", deviceInfo); + ReflectionUtils.setPrivateField(context, "timezone", "Asia/Kolkata"); + ReflectionUtils.setPrivateField(context, "sessionId", 1699538605l); + return context; + } + + private String getRudderContextJsonString(int i) { + return "{\"app\":{\"build\":\"2\",\"name\":\"rudderstack-android-sdk-desu\",\"namespace\":\"com.rudderstack.android.sdk.core\",\"version\":\"1.1\"},\"library\":{\"name\":\"com.rudderstack.android.sdk.core\",\"version\":\"1.20.1\"},\"os\":{\"name\":\"Android\",\"version\":\"14\"},\"screen\":{\"density\":3,\"width\":414,\"height\":736},\"userAgent\":\"Dalvik/2.1.0 (Linux; U; Android 14; sdk_gphone64_arm64 Build/UPB4.230623.005)\",\"locale\":\"en-US\",\"device\":{\"id\":\"10f9e80f-5342-48e0-8908-1b221179895b\",\"manufacturer\":\"Google\",\"model\":\"sdk_gphone64_arm64\",\"name\":\"emu64a\",\"type\":\"Android\"},\"network\":{\"carrier\":\"T-Mobile\",\"wifi\":true,\"bluetooth\":false,\"cellular\":true},\"timezone\":\"Asia/Kolkata\",\"sessionId\":1699538605,\"person\":{\"tier\":\"enterprise" + i + "\"},\"company\":{\"city\":\"city" + i + "\",\"name\":\"company" + i + "\"}}"; + } + + @Test + public void testRudderTraitsSerializationSynchronicity() { + AtomicInteger traitsSerialized = new AtomicInteger(0); + new Thread() { + @Override + public void run() { + super.run(); + for (int i = 1; i <= 3000; i++) { + RudderTraits traits = getTraits(i); + assertThat("traits got serialized perfectly", areJsonStringsEqual(RudderGson.getInstance().toJson(traits), getTraitsJsonString(i)), is(true)); + traitsSerialized.addAndGet(1); + } + } + }.start(); + new Thread() { + @Override + public void run() { + super.run(); + for (int i = 3001; i <= 6000; i++) { + RudderTraits traits = getTraits(i); + assertThat("traits got serialized perfectly", areJsonStringsEqual(RudderGson.getInstance().toJson(traits), getTraitsJsonString(i)), is(true)); + traitsSerialized.addAndGet(1); + } + } + }.start(); + new Thread() { + @Override + public void run() { + super.run(); + for (int i = 6001; i <= 9000; i++) { + RudderTraits traits = getTraits(i); + assertThat("traits got serialized perfectly", areJsonStringsEqual(RudderGson.getInstance().toJson(traits), getTraitsJsonString(i)), is(true)); + traitsSerialized.addAndGet(1); + } + } + }.start(); + await().atMost(60, SECONDS).until(() -> traitsSerialized.get() == 9000); + } + + private RudderTraits getTraits(int i) { + RudderTraits traits = new RudderTraits(); + traits.putName("User Name " + i); + traits.putEmail("user" + i + "@gmail.com"); + traits.putFirstName("User " + i); + traits.putLastName("Name " + i); + traits.put("key" + i, "value" + i); + traits.put("custom trait key" + i, "custom trait value" + i); + return traits; + } + + private String getTraitsJsonString(int i) { + return "{\"email\":\"user" + i + "@gmail.com\",\"firstname\":\"User " + i + "\",\"lastname\":\"Name " + i + "\",\"name\":\"User Name " + i + "\",\"key" + i + "\":\"value" + i + "\",\"custom trait key" + i + "\":\"custom trait value" + i + "\"}"; + } + + @Test + public void testJSONArrayJSONObjectSerializationSynchronicity() { + AtomicInteger messagesSerialized = new AtomicInteger(0); + new Thread(() -> { + try (MockedStatic utilities = Mockito.mockStatic(Utils.class)) { + utilities.when(Utils::getTimeStamp).thenReturn("2022-03-14T06:46:41.365Z"); + for (int i = 1; i <= 1000; i++) { + RudderMessage trackMessage = getTrackMessage(i); + assertThat("track message got serialized perfectly", areJsonStringsEqual(RudderGson.getInstance().toJson(trackMessage), getTrackJsonString(i, trackMessage)), is(true)); + RudderMessage identifyMessage = getIdentifyMessage(i); + assertThat("identify message got serialized perfectly", areJsonStringsEqual(RudderGson.getInstance().toJson(identifyMessage), getIdentifyJsonString(i, identifyMessage)), is(true)); + messagesSerialized.addAndGet(2); + } + } + }, "serialize-rudder-message-thread-1") { + }.start(); + + new Thread(() -> { + try (MockedStatic utilities = Mockito.mockStatic(Utils.class)) { + utilities.when(Utils::getTimeStamp).thenReturn("2022-03-14T06:46:41.365Z"); + for (int i = 1001; i <= 2000; i++) { + RudderMessage trackMessage = getTrackMessage(i); + assertThat("track message got serialized perfectly", areJsonStringsEqual(RudderGson.getInstance().toJson(trackMessage), getTrackJsonString(i, trackMessage)), is(true)); + RudderMessage identifyMessage = getIdentifyMessage(i); + assertThat("identify message got serialized perfectly", areJsonStringsEqual(RudderGson.getInstance().toJson(identifyMessage), getIdentifyJsonString(i, identifyMessage)), is(true)); + messagesSerialized.addAndGet(2); + } + } + }, "serialize-rudder-message-thread-2") { + }.start(); + + await().atMost(60, SECONDS).until(() -> messagesSerialized.get() == 4000); + + } + + private String getTrackJsonString(int i, RudderMessage message) { + return "{\"messageId\":\"" + message.getMessageId() + "\",\"channel\":\"mobile\",\"context\":{},\"originalTimestamp\":\"2022-03-14T06:46:41.365Z\",\"event\":\"TestEvent" + i + "\",\"properties\":{\"pinId " + i + "\":2351636,\"userLocationLatitude " + i + "\":55.661663449562205,\"locationsBefore " + i + "\":[{\"latitude " + i + "\":55.66132122924984,\"longitude " + i + "\":12.51671169784383},{\"latitude " + i + "\":55.661428115890374,\"longitude " + i + "\":12.51677390468785},{\"latitude " + i + "\":55.661663449562205,\"longitude " + i + "\":12.516869940636775}],\"userLocationLongitude " + i + "\":12.516869940636775},\"integrations\":{}}"; + } + + private String getIdentifyJsonString(int i, RudderMessage message) { + return "{\"messageId\":\"" + message.getMessageId() + "\",\"channel\":\"mobile\",\"context\":{},\"originalTimestamp\":\"2022-03-14T06:46:41.365Z\",\"userId\":\"user name " + i + "\",\"event\":\"identify\",\"integrations\":{}}"; + } + + private RudderMessage getIdentifyMessage(int i) { + RudderMessage message = new RudderMessageBuilder() + .setEventName(MessageType.IDENTIFY) + .setUserId("user name " + i) + .build(); + return message; + } + + private RudderMessage getTrackMessage(int i) { + HashMap jsonData = new HashMap(); + jsonData.put("pinId " + i, 2351636); + jsonData.put("userLocationLongitude " + i, 12.516869940636775); + jsonData.put("userLocationLatitude " + i, 55.661663449562205); + JSONArray locationsBefore = new JSONArray(); + try { + locationsBefore.put(new JSONObject().put("latitude " + i, 55.66132122924984).put("longitude " + i, 12.51671169784383)); + locationsBefore.put(new JSONObject().put("latitude " + i, 55.661428115890374).put("longitude " + i, 12.51677390468785)); + locationsBefore.put(new JSONObject().put("latitude " + i, 55.661663449562205).put("longitude " + i, 12.516869940636775)); + } catch (JSONException e) { + throw new RuntimeException(e); + } + jsonData.put("locationsBefore " + i, locationsBefore); + return new RudderMessageBuilder().setEventName("TestEvent" + i).setProperty(jsonData).build(); + } + + public boolean areJsonStringsEqual(String json1, String json2) { + JsonObject obj1 = JsonParser.parseString(json1).getAsJsonObject(); + JsonObject obj2 = JsonParser.parseString(json2).getAsJsonObject(); + boolean result = obj1.equals(obj2); + return result; + } +} diff --git a/dummy-impl/src/main/java/com/rudderstack/android/integration/dummy/DummyGAIntegrationImpl.java b/dummy-impl/src/main/java/com/rudderstack/android/integration/dummy/DummyGAIntegrationImpl.java index 66f9f049f..27b5dcbce 100644 --- a/dummy-impl/src/main/java/com/rudderstack/android/integration/dummy/DummyGAIntegrationImpl.java +++ b/dummy-impl/src/main/java/com/rudderstack/android/integration/dummy/DummyGAIntegrationImpl.java @@ -1,13 +1,10 @@ package com.rudderstack.android.integration.dummy; -import com.google.gson.Gson; import com.rudderstack.android.sdk.core.RudderClient; import com.rudderstack.android.sdk.core.RudderConfig; import com.rudderstack.android.sdk.core.RudderIntegration; import com.rudderstack.android.sdk.core.RudderMessage; -import org.json.JSONException; -import org.json.JSONObject; import java.util.Map; From 44e4af8c669acbbe046b98c99c37523da12c4869 Mon Sep 17 00:00:00 2001 From: GitHub actions Date: Tue, 14 Nov 2023 09:12:34 +0000 Subject: [PATCH 3/3] chore(release): 1.21.0 --- CHANGELOG.md | 12 ++++++++++++ gradle.properties | 4 ++-- package.json | 2 +- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 25538c911..fbf19121c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,18 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. +## [1.21.0](https://github.com/rudderlabs/rudder-sdk-android/compare/v1.20.2...v1.21.0) (2023-11-14) + + +### Features + +* added support for JSONObject and JSONArray as part of RudderMessage object ([#350](https://github.com/rudderlabs/rudder-sdk-android/issues/350)) ([c9bb58f](https://github.com/rudderlabs/rudder-sdk-android/commit/c9bb58f7e2e2b76f9aaed817e36d5f46c3b86bab)) + + +### Bug Fixes + +* update lastActiveTimestamp value when reset call is made ([#360](https://github.com/rudderlabs/rudder-sdk-android/issues/360)) ([7596d71](https://github.com/rudderlabs/rudder-sdk-android/commit/7596d718fa63dda0e1d5cb683749acfc6691b295)) + ### [1.20.2](https://github.com/rudderlabs/rudder-sdk-android/compare/v1.20.1...v1.20.2) (2023-11-01) diff --git a/gradle.properties b/gradle.properties index ba990d4e5..394a623b8 100644 --- a/gradle.properties +++ b/gradle.properties @@ -5,8 +5,8 @@ android.enableJetifier=true android.enableR8.fullMode=true kotlin.code.style=official GROUP=com.rudderstack.android.sdk -VERSION_CODE=21 -VERSION_NAME=1.20.2 +VERSION_CODE=22 +VERSION_NAME=1.21.0 POM_NAME=Rudderstack SDK for android POM_DESCRIPTION=Rudderstack SDK for android POM_ARTIFACT_ID=core diff --git a/package.json b/package.json index fe54ebffe..abafb34ba 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "version": "1.20.2", + "version": "1.21.0", "dependencies": { "properties-reader": "^2.2.0" }