Skip to content

Commit 197754e

Browse files
committed
Merge branch 'release/4.0.2'
2 parents 772257d + f43452d commit 197754e

File tree

4 files changed

+252
-55
lines changed

4 files changed

+252
-55
lines changed

AndroidSDKCore/src/main/java/com/leanplum/internal/Constants.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ public class Constants {
3636
public static int SOCKET_PORT = 80;
3737
public static int NETWORK_TIMEOUT_SECONDS = 10;
3838
public static int NETWORK_TIMEOUT_SECONDS_FOR_DOWNLOADS = 10;
39-
public static String LEANPLUM_VERSION = "4.0.1";
39+
public static String LEANPLUM_VERSION = "4.0.2";
4040
public static String CLIENT = "android";
4141

4242
static final String LEANPLUM_PACKAGE_IDENTIFIER = BuildConfig.LEANPLUM_PACKAGE_IDENTIFIER;

AndroidSDKCore/src/main/java/com/leanplum/internal/Request.java

Lines changed: 112 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -235,30 +235,34 @@ private void saveRequestForLater(final Map<String, Object> args) {
235235
LeanplumEventDataManager.executeAsyncTask(new AsyncTask<Void, Void, Void>() {
236236
@Override
237237
protected Void doInBackground(Void... params) {
238-
synchronized (Request.class) {
239-
Context context = Leanplum.getContext();
240-
SharedPreferences preferences = context.getSharedPreferences(
241-
LEANPLUM, Context.MODE_PRIVATE);
242-
SharedPreferences.Editor editor = preferences.edit();
243-
long count = LeanplumEventDataManager.getEventsCount();
244-
String uuid = preferences.getString(Constants.Defaults.UUID_KEY, null);
245-
if (uuid == null || count % MAX_EVENTS_PER_API_CALL == 0) {
246-
uuid = UUID.randomUUID().toString();
247-
editor.putString(Constants.Defaults.UUID_KEY, uuid);
248-
SharedPreferencesUtil.commitChanges(editor);
249-
}
250-
args.put(UUID_KEY, uuid);
251-
LeanplumEventDataManager.insertEvent(JsonConverter.toJson(args));
252-
253-
dataBaseIndex = count;
254-
// Checks if here response and/or error callback for this request. We need to add callbacks to
255-
// eventCallbackManager only if here was internet connection, otherwise triggerErrorCallback
256-
// will handle error callback for this event.
257-
if (response != null || error != null && !Util.isConnected()) {
258-
eventCallbackManager.addCallbacks(currentRequest, response, error);
238+
try {
239+
synchronized (Request.class) {
240+
Context context = Leanplum.getContext();
241+
SharedPreferences preferences = context.getSharedPreferences(
242+
LEANPLUM, Context.MODE_PRIVATE);
243+
SharedPreferences.Editor editor = preferences.edit();
244+
long count = LeanplumEventDataManager.getEventsCount();
245+
String uuid = preferences.getString(Constants.Defaults.UUID_KEY, null);
246+
if (uuid == null || count % MAX_EVENTS_PER_API_CALL == 0) {
247+
uuid = UUID.randomUUID().toString();
248+
editor.putString(Constants.Defaults.UUID_KEY, uuid);
249+
SharedPreferencesUtil.commitChanges(editor);
250+
}
251+
args.put(UUID_KEY, uuid);
252+
LeanplumEventDataManager.insertEvent(JsonConverter.toJson(args));
253+
254+
dataBaseIndex = count;
255+
// Checks if here response and/or error callback for this request. We need to add callbacks to
256+
// eventCallbackManager only if here was internet connection, otherwise triggerErrorCallback
257+
// will handle error callback for this event.
258+
if (response != null || error != null && !Util.isConnected()) {
259+
eventCallbackManager.addCallbacks(currentRequest, response, error);
260+
}
259261
}
260-
return null;
262+
} catch (Throwable t) {
263+
Util.handleException(t);
261264
}
265+
return null;
262266
}
263267
});
264268
}
@@ -333,7 +337,7 @@ private void triggerErrorCallback(Exception e) {
333337
error.error(e);
334338
}
335339
if (apiResponse != null) {
336-
List<Map<String, Object>> requests = getUnsentRequests();
340+
List<Map<String, Object>> requests = getUnsentRequests(1.0);
337341
List<Map<String, Object>> requestsToSend = removeIrrelevantBackgroundStartRequests(requests);
338342
apiResponse.response(requestsToSend, null, requests.size());
339343
}
@@ -466,28 +470,98 @@ private void sendNow() {
466470
Util.executeAsyncTask(true, new AsyncTask<Void, Void, Void>() {
467471
@Override
468472
protected Void doInBackground(Void... params) {
469-
sendRequests();
473+
try {
474+
sendRequests();
475+
} catch (Throwable t) {
476+
Util.handleException(t);
477+
}
470478
return null;
471479
}
472480
});
473481
}
474482

475-
private void sendRequests() {
483+
484+
/**
485+
* This class wraps the unsent requests, requests that we need to send
486+
* and the JSON encoded string. Wrapping it in the class allows us to
487+
* retain consistency in the requests we are sending and the actual
488+
* JSON string.
489+
*/
490+
static class RequestsWithEncoding {
491+
List<Map<String, Object>> unsentRequests;
492+
List<Map<String, Object>> requestsToSend;
493+
String jsonEncodedString;
494+
}
495+
496+
private RequestsWithEncoding getRequestsWithEncodedStringForErrors() {
476497
List<Map<String, Object>> unsentRequests = new ArrayList<>();
477498
List<Map<String, Object>> requestsToSend;
499+
String jsonEncodedRequestsToSend;
500+
501+
String uuid = UUID.randomUUID().toString();
502+
for (Map<String, Object> error : localErrors) {
503+
error.put(UUID_KEY, uuid);
504+
unsentRequests.add(error);
505+
}
506+
requestsToSend = unsentRequests;
507+
jsonEncodedRequestsToSend = jsonEncodeUnsentRequests(unsentRequests);
508+
509+
RequestsWithEncoding requestsWithEncoding = new RequestsWithEncoding();
510+
// for errors, we send all unsent requests so they are identical
511+
requestsWithEncoding.unsentRequests = unsentRequests;
512+
requestsWithEncoding.requestsToSend = requestsToSend;
513+
requestsWithEncoding.jsonEncodedString = jsonEncodedRequestsToSend;
514+
515+
return requestsWithEncoding;
516+
}
517+
518+
519+
protected RequestsWithEncoding getRequestsWithEncodedStringStoredRequests(double fraction) {
520+
try {
521+
List<Map<String, Object>> unsentRequests;
522+
List<Map<String, Object>> requestsToSend;
523+
String jsonEncodedRequestsToSend;
524+
RequestsWithEncoding requestsWithEncoding = new RequestsWithEncoding();
525+
526+
if (fraction < 0.01) { //base case
527+
unsentRequests = new ArrayList<>(0);
528+
requestsToSend = new ArrayList<>(0);
529+
} else {
530+
unsentRequests = getUnsentRequests(fraction);
531+
requestsToSend = removeIrrelevantBackgroundStartRequests(unsentRequests);
532+
}
533+
534+
jsonEncodedRequestsToSend = jsonEncodeUnsentRequests(unsentRequests);
535+
requestsWithEncoding.unsentRequests = unsentRequests;
536+
requestsWithEncoding.requestsToSend = requestsToSend;
537+
requestsWithEncoding.jsonEncodedString = jsonEncodedRequestsToSend;
538+
539+
return requestsWithEncoding;
540+
} catch (OutOfMemoryError E) {
541+
// half the requests will need less memory, recursively
542+
return getRequestsWithEncodedStringStoredRequests(0.5 * fraction);
543+
}
544+
}
545+
546+
private RequestsWithEncoding getRequestsWithEncodedString() {
547+
RequestsWithEncoding requestsWithEncoding;
478548
// Check if we have localErrors, if yes then we will send only errors to the server.
479549
if (localErrors.size() != 0) {
480-
String uuid = UUID.randomUUID().toString();
481-
for (Map<String, Object> error : localErrors) {
482-
error.put(UUID_KEY, uuid);
483-
unsentRequests.add(error);
484-
}
485-
requestsToSend = unsentRequests;
550+
requestsWithEncoding = getRequestsWithEncodedStringForErrors();
486551
} else {
487-
unsentRequests = getUnsentRequests();
488-
requestsToSend = removeIrrelevantBackgroundStartRequests(unsentRequests);
552+
requestsWithEncoding = getRequestsWithEncodedStringStoredRequests(1.0);
489553
}
490554

555+
return requestsWithEncoding;
556+
}
557+
558+
private void sendRequests() {
559+
RequestsWithEncoding requestsWithEncoding = getRequestsWithEncodedString();
560+
561+
List<Map<String, Object>> unsentRequests = requestsWithEncoding.unsentRequests;
562+
List<Map<String, Object>> requestsToSend = requestsWithEncoding.requestsToSend;
563+
String jsonEncodedString = requestsWithEncoding.jsonEncodedString;
564+
491565
if (requestsToSend.isEmpty()) {
492566
return;
493567
}
@@ -496,7 +570,7 @@ private void sendRequests() {
496570
if (!Request.attachApiKeys(multiRequestArgs)) {
497571
return;
498572
}
499-
multiRequestArgs.put(Constants.Params.DATA, jsonEncodeUnsentRequests(requestsToSend));
573+
multiRequestArgs.put(Constants.Params.DATA, jsonEncodedString);
500574
multiRequestArgs.put(Constants.Params.SDK_VERSION, Constants.LEANPLUM_VERSION);
501575
multiRequestArgs.put(Constants.Params.ACTION, Constants.Methods.MULTI);
502576
multiRequestArgs.put(Constants.Params.TIME, Double.toString(new Date().getTime() / 1000.0));
@@ -589,7 +663,7 @@ static void deleteSentRequests(int requestsCount) {
589663
}
590664
}
591665

592-
private static List<Map<String, Object>> getUnsentRequests() {
666+
public List<Map<String, Object>> getUnsentRequests(double fraction) {
593667
List<Map<String, Object>> requestData;
594668

595669
synchronized (Request.class) {
@@ -598,8 +672,8 @@ private static List<Map<String, Object>> getUnsentRequests() {
598672
SharedPreferences preferences = context.getSharedPreferences(
599673
LEANPLUM, Context.MODE_PRIVATE);
600674
SharedPreferences.Editor editor = preferences.edit();
601-
602-
requestData = LeanplumEventDataManager.getEvents(MAX_EVENTS_PER_API_CALL);
675+
int count = (int) (fraction * MAX_EVENTS_PER_API_CALL);
676+
requestData = LeanplumEventDataManager.getEvents(count);
603677
editor.remove(Constants.Defaults.UUID_KEY);
604678
SharedPreferencesUtil.commitChanges(editor);
605679
}
@@ -646,7 +720,7 @@ private static List<Map<String, Object>> removeIrrelevantBackgroundStartRequests
646720
return relevantRequests;
647721
}
648722

649-
private static String jsonEncodeUnsentRequests(List<Map<String, Object>> requestData) {
723+
protected static String jsonEncodeUnsentRequests(List<Map<String, Object>> requestData) {
650724
Map<String, Object> data = new HashMap<>();
651725
data.put(Constants.Params.DATA, requestData);
652726
return JsonConverter.toJson(data);

AndroidSDKTests/src/test/java/com/leanplum/LeanplumTest.java

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -398,14 +398,16 @@ public void testCrashes() throws Exception {
398398
LeanplumEventDataManager.init(Leanplum.getContext());
399399

400400
// Add two events to database.
401-
new Request("POST", Constants.Methods.GET_INBOX_MESSAGES, null).sendEventually();
402-
new Request("POST", Constants.Methods.LOG, null).sendEventually();
401+
Request request1 = new Request("POST", Constants.Methods.GET_INBOX_MESSAGES, null);
402+
Request request2 = new Request("POST", Constants.Methods.LOG, null);
403403

404+
request1.sendEventually();
405+
request2.sendEventually();
406+
407+
final double fraction = 1.0;
404408
// Get a number of events in the database.
405409
// Expectation: 2 events.
406-
Method getUnsentRequests = Request.class.getDeclaredMethod("getUnsentRequests");
407-
getUnsentRequests.setAccessible(true);
408-
List unsentRequests = (List) getUnsentRequests.invoke(Request.class);
410+
List unsentRequests = request1.getUnsentRequests(fraction);
409411
assertNotNull(unsentRequests);
410412
assertEquals(2, unsentRequests.size());
411413

@@ -427,7 +429,7 @@ public void testCrashes() throws Exception {
427429

428430
// Get a number of events in the database. Checks if ours two events still here.
429431
// Expectation: 2 events.
430-
unsentRequests = (List) getUnsentRequests.invoke(Request.class);
432+
unsentRequests = request1.getUnsentRequests(fraction);
431433
assertNotNull(unsentRequests);
432434
assertEquals(2, unsentRequests.size());
433435

@@ -444,7 +446,7 @@ public void onRequest(String httpMethod, String apiMethod, Map<String, Object> p
444446

445447
// Get a number of events in the database. Make sure we sent all events.
446448
// Expectation: 0 events.
447-
unsentRequests = (List) getUnsentRequests.invoke(Request.class);
449+
unsentRequests = request1.getUnsentRequests(fraction);
448450
assertNotNull(unsentRequests);
449451
assertEquals(0, unsentRequests.size());
450452

0 commit comments

Comments
 (0)