Skip to content

Commit 6fadb74

Browse files
committed
release: SDK 3.4.0
1 parent c0db2c9 commit 6fadb74

40 files changed

Lines changed: 12252 additions & 106 deletions

Sources/gradle/libs.versions.toml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[versions]
2-
agp = "8.13.1"
2+
agp = "8.13.2"
33
android = "4.1.1.4"
4-
androidCompileSdk = "36"
4+
androidCompileSdk = "37"
55
androidMinSdk = "21"
66
androidLint = "31.13.1"
77
androidxJunit = "1.2.1"
@@ -11,9 +11,9 @@ androidXTestCoreKtx = "1.6.1"
1111
androidXTestRunner = "1.6.2"
1212
androidXTestTruth = "1.6.0"
1313
assertjCore = "3.24.2"
14-
batchSdk = "3.3.0"
15-
batchApiLevel = "330"
16-
batchMessagingApiLevel = "33"
14+
batchSdk = "3.4.0"
15+
batchApiLevel = "340"
16+
batchMessagingApiLevel = "34"
1717
batchResourcePrefix = "com_batchsdk_"
1818
batchNamespace = "com.batch.android"
1919
batchTestNamespace = "com.batch.android.test"
@@ -36,7 +36,7 @@ metalava = "1.0.0-alpha04"
3636
mockitoCore = "5.12.0"
3737
nexusStaging = "0.30.0"
3838
powermockClassloadingXstream = "2.0.9"
39-
robolectric = "4.9.2"
39+
robolectric = "4.16.1"
4040
testify = "3.2.2"
4141

4242
[libraries]

Sources/sdk/build.gradle.kts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,9 @@ plugins {
1212
base { archivesName.set("Batch") }
1313

1414
android {
15-
compileSdk = libs.versions.androidCompileSdk.get().toInt()
16-
15+
compileSdk {
16+
version = release(libs.versions.androidCompileSdk.get().toInt()) { minorApiLevel = 0 }
17+
}
1718
resourcePrefix = libs.versions.batchResourcePrefix.get()
1819
namespace = libs.versions.batchNamespace.get()
1920
testNamespace = libs.versions.batchTestNamespace.get()

Sources/sdk/src/main/java/com/batch/android/AttributesCheckWebservice.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import com.batch.android.core.TaskRunnable;
77
import com.batch.android.core.domain.DomainURLBuilder;
88
import com.batch.android.json.JSONObject;
9+
import com.batch.android.module.UserModule;
910
import com.batch.android.query.AttributesCheckQuery;
1011
import com.batch.android.query.Query;
1112
import com.batch.android.query.QueryType;
@@ -49,7 +50,7 @@ protected AttributesCheckWebservice(
4950
AttributesCheckWebserviceListener listener
5051
) throws MalformedURLException {
5152
super(context, RequestType.POST, DomainURLBuilder.ATTR_CHECK_WS_URL);
52-
if (version <= 0) {
53+
if (version <= 0 && version != UserModule.ATC_CHANGESET_FOR_MIGRATIONS) {
5354
throw new IllegalArgumentException("version <= 0");
5455
}
5556

Sources/sdk/src/main/java/com/batch/android/BatchEventAttributes.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ private BatchEventAttributes putTypedAttribute(@NonNull String key, @NonNull Eve
218218
/**
219219
* Validate the event data.
220220
*
221-
* @return A list of human readable errors as strings if the event data does not validates successfully, An empty list if not. If the data does not validate, Batch will refuse to track an event with it.
221+
* @return A list of human-readable errors as strings if the event data does not validate successfully, An empty list if not. If the data does not validate, Batch will refuse to track an event with it.
222222
*/
223223
public List<String> validateEventAttributes() {
224224
return EventAttributesValidator.computeValidationErrors(this);

Sources/sdk/src/main/java/com/batch/android/BatchProfileAttributeEditor.java

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -404,10 +404,11 @@ public BatchProfileAttributeEditor setAttribute(final @NonNull String key, final
404404
public BatchProfileAttributeEditor setAttribute(final @NonNull String key, final @NonNull List<String> value) {
405405
try {
406406
String normalizedKey = ProfileDataHelper.normalizeAttributeKey(key);
407-
ProfileDataHelper.validateStringArray(value);
407+
List<String> deduped = ProfileDataHelper.deduplicateKeepLast(value);
408+
ProfileDataHelper.validateStringArray(deduped);
408409
this.profileUpdateOperation.addAttribute(
409410
normalizedKey,
410-
new UserAttribute(new ProfileStringArrayAttribute(value), AttributeType.STRING_ARRAY)
411+
new UserAttribute(new ProfileStringArrayAttribute(deduped), AttributeType.STRING_ARRAY)
411412
);
412413
} catch (AttributeValidationException e) {
413414
e.printErrorMessage(TAG, key);
@@ -532,14 +533,20 @@ public BatchProfileAttributeEditor removeFromArray(final @NonNull String key, fi
532533
}
533534

534535
/**
535-
* Save all of the pending changes made in that editor.
536+
* Save all the pending changes made in that editor.
537+
* <p>
536538
* Note if Batch is not started, your changes will be enqueue until it start.
537539
* Once you called "save", you need to get a new editor in order to make further changes.
538540
* <p>
539541
* This action cannot be undone.
542+
* <p>
543+
* The pending changes on the editor cannot weigh more than 25kB or the entire
544+
* request will be rejected.
540545
*/
541546
public void save() {
542-
super.save();
543-
ProfileModuleProvider.get().handleProfileDataChanged(this.profileUpdateOperation);
547+
if (ProfileModuleProvider.get().handleProfileDataChanged(this.profileUpdateOperation)) {
548+
// Handle MEP compat only when CEP event pass validation
549+
super.save();
550+
}
544551
}
545552
}

Sources/sdk/src/main/java/com/batch/android/TrackerWebservice.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import com.batch.android.core.TaskRunnable;
77
import com.batch.android.core.domain.DomainURLBuilder;
88
import com.batch.android.event.Event;
9+
import com.batch.android.event.ProfileIdentifyDeduplicator;
910
import com.batch.android.json.JSONObject;
1011
import com.batch.android.query.Query;
1112
import com.batch.android.query.TrackingQuery;
@@ -57,7 +58,13 @@ protected boolean canBypassOptOut() {
5758
protected List<Query> getQueries() {
5859
List<Query> queries = new ArrayList<>(1);
5960

60-
queries.add(new TrackingQuery(applicationContext, events));
61+
// Remove useless duplicated _PROFILE_IDENTIFY events.
62+
// Doing this here, since event are still in db and should be deleted when
63+
// success callback is called
64+
List<Event> deduplicatedEvents = ProfileIdentifyDeduplicator.deduplicate(events);
65+
66+
// Add events to query for serialization
67+
queries.add(new TrackingQuery(applicationContext, deduplicatedEvents));
6168

6269
return queries;
6370
}

Sources/sdk/src/main/java/com/batch/android/core/Webservice.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -489,7 +489,7 @@ public byte[] executeRequest() throws WebserviceError {
489489

490490
if (isResponseValid(responseCode)) {
491491
/// If URL was build with `canCheckOriginalDomainAvailability` to override current domain so success means that the original domain is now available
492-
String host = buildURL().getHost();
492+
String host = builder.build().getHost();
493493
if (domainManager.isOriginalDomain(host) && !domainManager.isCurrentDomain(host)) {
494494
domainManager.resetDomainToOriginal();
495495
}

Sources/sdk/src/main/java/com/batch/android/core/systemparameters/SystemParameterHelper.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -269,10 +269,11 @@ public static JSONObject serializeSystemParameters(@NonNull List<WatchedSystemPa
269269
if (paramKey == null) {
270270
continue;
271271
}
272-
serializedParameters.put(
273-
paramKey,
274-
parameter.getLastValue() != null ? parameter.getLastValue() : JSONObject.NULL
275-
);
272+
Object paramValue = JSONObject.NULL;
273+
if (parameter.isAllowed() && parameter.getLastValue() != null) {
274+
paramValue = parameter.getLastValue();
275+
}
276+
serializedParameters.put(paramKey, paramValue);
276277
}
277278
return serializedParameters;
278279
}

Sources/sdk/src/main/java/com/batch/android/core/systemparameters/SystemParameterRegistry.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,12 +151,18 @@ private SystemParameterRegistry(@NonNull Context context) {
151151
SystemParameter bridgeVersion = new WatchedSystemParameter(
152152
context,
153153
SystemParameterShortName.BRIDGE_VERSION,
154-
SystemParameterHelper::getBridgeVersion
154+
() -> {
155+
String version = SystemParameterHelper.getBridgeVersion();
156+
return version.isEmpty() ? null : version;
157+
}
155158
);
156159
SystemParameter pluginVersion = new WatchedSystemParameter(
157160
context,
158161
SystemParameterShortName.PLUGIN_VERSION,
159-
SystemParameterHelper::getPluginVersion
162+
() -> {
163+
String version = SystemParameterHelper.getPluginVersion();
164+
return version.isEmpty() ? null : version;
165+
}
160166
);
161167

162168
parameters.add(installId);

Sources/sdk/src/main/java/com/batch/android/event/EventAttributesValidator.java

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
package com.batch.android.event;
22

3+
import androidx.annotation.NonNull;
34
import com.batch.android.BatchEventAttributes;
5+
import com.batch.android.json.JSONException;
6+
import com.batch.android.json.JSONObject;
47
import com.batch.android.user.AttributeType;
58
import java.net.URI;
9+
import java.nio.charset.StandardCharsets;
610
import java.util.ArrayList;
711
import java.util.Collections;
8-
import java.util.Date;
912
import java.util.List;
13+
import java.util.Locale;
1014
import java.util.Map;
1115
import java.util.regex.Pattern;
1216

@@ -16,7 +20,7 @@
1620
public class EventAttributesValidator {
1721

1822
/**
19-
* Class that hold a human readable error.
23+
* Class that hold a human-readable error.
2024
*/
2125
private static class ValidationError {
2226

@@ -71,6 +75,8 @@ public List<String> getItems() {
7175
}
7276
}
7377

78+
public static final int MAX_PAYLOAD_SIZE_BYTES = 25 * 1024;
79+
7480
private static final int LABEL_MAX_LENGTH = 200;
7581
private static final int TAG_MAX_LENGTH = 64;
7682
private static final int TAGS_MAX_COUNT = 10;
@@ -84,12 +90,32 @@ public static boolean isEventNameValid(String eventName) {
8490
return attributeNameRegexp.matcher(eventName).matches();
8591
}
8692

93+
public static boolean exceedsMaxPayloadSize(@NonNull String serializedPayload) {
94+
return serializedPayload.getBytes(StandardCharsets.UTF_8).length > MAX_PAYLOAD_SIZE_BYTES;
95+
}
96+
8797
public static List<String> computeValidationErrors(BatchEventAttributes eventData) {
8898
List<String> errors = new ArrayList<>();
8999
List<ValidationError> validationErrors = visitObject(eventData, new Breadcrumbs(new ArrayList<>()));
90100
for (ValidationError validationError : validationErrors) {
91101
errors.add(validationError.render());
92102
}
103+
if (errors.isEmpty()) {
104+
try {
105+
JSONObject serialized = EventAttributesSerializer.serialize(eventData);
106+
if (exceedsMaxPayloadSize(serialized.toString())) {
107+
errors.add(
108+
String.format(
109+
Locale.US,
110+
"<attributes root>: payload exceeds the maximum allowed size (%d kB)",
111+
MAX_PAYLOAD_SIZE_BYTES / 1024
112+
)
113+
);
114+
}
115+
} catch (JSONException ignored) {
116+
// serialization errors are caught later by the caller
117+
}
118+
}
93119
return errors;
94120
}
95121

0 commit comments

Comments
 (0)