Skip to content

Commit be80e5f

Browse files
committed
Merge branch 'master' into release/4.2.7
2 parents 2abd964 + 2540a7f commit be80e5f

File tree

16 files changed

+196
-74
lines changed

16 files changed

+196
-74
lines changed

.github/PULL_REQUEST_TEMPLATE.md

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
1-
Fixes #
1+
What | Where/Who
2+
------------------|----------------------------------------
3+
JIRA Issue | [JIRA_TICKET_ID](https://leanplum.atlassian.net/browse/JIRA_TICKET_ID)
4+
People Involved | @colleague1, @colleague2
25

3-
## Proposed Changes
6+
[Notes on PR descriptions](https://leanplum.atlassian.net/wiki/spaces/PR/pages/288424408/Creating+a+GitHub+Pull+Request)
47

5-
-
6-
-
7-
-
8+
## Background
89

10+
## Implementation
11+
12+
## Testing steps
13+
14+
## Is this change backwards-compatible?

AndroidSDKCore/src/main/java/com/leanplum/Leanplum.java

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -626,7 +626,7 @@ private static void checkAndStartNotificationsModules() {
626626

627627
private static void startHelper(
628628
String userId, final Map<String, ?> attributes, final boolean isBackground) {
629-
LeanplumEventDataManager.init(context);
629+
LeanplumEventDataManager.sharedInstance();
630630
checkAndStartNotificationsModules();
631631
Boolean limitAdTracking = null;
632632
String deviceId = RequestOld.deviceId();
@@ -812,6 +812,8 @@ protected Void doInBackground(Void... params) {
812812
if (variants == null) {
813813
Log.d("No variants received from the server.");
814814
}
815+
Map<String, String> filenameToURLs = parseFilenameToURLs(response);
816+
FileManager.setFilenameToURLs(filenameToURLs);
815817

816818
if (BuildUtil.isNotificationChannelSupported(context)) {
817819
// Get notification channels and groups.
@@ -2110,6 +2112,8 @@ public void response(JSONObject response) {
21102112
}
21112113

21122114
parseVariantDebugInfo(response);
2115+
Map<String, String> filenameToURLs = parseFilenameToURLs(response);
2116+
FileManager.setFilenameToURLs(filenameToURLs);
21132117
}
21142118
if (callback != null) {
21152119
OsHandler.getInstance().post(callback);
@@ -2228,6 +2232,7 @@ public static Map<String, Object> getVariantDebugInfo() {
22282232
*/
22292233
public static void setDeviceLocation(Location location) {
22302234
setDeviceLocation(location, LeanplumLocationAccuracyType.CELL);
2235+
Leanplum.countAggregator().incrementCount("setDeviceLocation");
22312236
}
22322237

22332238
/**
@@ -2243,6 +2248,7 @@ public static void setDeviceLocation(Location location, LeanplumLocationAccuracy
22432248
"call setDeviceLocation. If you prefer to always set location manually, " +
22442249
"then call disableLocationCollection.");
22452250
}
2251+
Leanplum.countAggregator().incrementCount("setDeviceLocation_type");
22462252
LeanplumInternal.setUserLocationAttribute(location, type,
22472253
new LeanplumInternal.locationAttributeRequestsCallback() {
22482254
@Override
@@ -2304,6 +2310,16 @@ public static Set<String> parseFeatureFlags(JSONObject response) {
23042310
return featureFlagSet;
23052311
}
23062312

2313+
@VisibleForTesting
2314+
public static Map<String, String> parseFilenameToURLs(JSONObject response) {
2315+
JSONObject filesObject = response.optJSONObject(
2316+
Constants.Keys.FILES);
2317+
if (filesObject != null) {
2318+
return JsonConverter.mapFromJson(filesObject);
2319+
}
2320+
return null;
2321+
}
2322+
23072323
private static Set<String> toSet(JSONArray array) {
23082324
Set<String> set = new HashSet<>();
23092325
if (array != null) {

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,7 @@ public static class Keys {
212212
public static final String LOGGING_ENABLED = "loggingEnabled";
213213
public static final String ENABLED_COUNTERS = "enabledSdkCounters";
214214
public static final String ENABLED_FEATURE_FLAGS = "enabledFeatureFlags";
215+
public static final String FILES = "files";
215216
public static final String TIMEZONE = "timezone";
216217
public static final String TIMEZONE_OFFSET_SECONDS = "timezoneOffsetSeconds";
217218
public static final String TITLE = "Title";

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ interface ResourceUpdateCallback {
6666
private static boolean initializing = false;
6767
static final Object initializingLock = new Object();
6868
public static Var<HashMap<String, Object>> resources = null;
69+
public static Map<String, String> filenameToURLs = null;
6970

7071
public enum DownloadFileResult {
7172
NONE,
@@ -108,6 +109,9 @@ public static DownloadFileResult maybeDownloadFile(boolean isResource, String st
108109
if (!FileManager.fileExistsAtPath(realPath)) {
109110
realPath = FileManager.fileRelativeToDocuments(stringValue);
110111
if (!FileManager.fileExistsAtPath(realPath)) {
112+
if (FileManager.filenameToURLs != null && FileManager.filenameToURLs.containsKey(stringValue) && urlValue == null) {
113+
urlValue = FileManager.filenameToURLs.get(stringValue);
114+
}
111115
RequestOld downloadRequest = RequestOld.get(Constants.Methods.DOWNLOAD_FILE, null);
112116
downloadRequest.onResponse(new RequestOld.ResponseCallback() {
113117
@Override
@@ -185,6 +189,10 @@ public static boolean fileExistsAtPath(String path) {
185189
return path != null && new File(path).exists();
186190
}
187191

192+
public static void setFilenameToURLs(Map<String, String> filenameToURLs) {
193+
FileManager.filenameToURLs = filenameToURLs;
194+
}
195+
188196
@SuppressWarnings("SameReturnValue")
189197
private static String appBundlePath() {
190198
return "";

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

Lines changed: 43 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -48,53 +48,58 @@
4848
* @author Anna Orlova
4949
*/
5050
public class LeanplumEventDataManager {
51+
52+
private static LeanplumEventDataManager instance;
53+
5154
private static final String DATABASE_NAME = "__leanplum.db";
5255
private static final int DATABASE_VERSION = 1;
5356
private static final String EVENT_TABLE_NAME = "event";
5457
private static final String COLUMN_DATA = "data";
5558
private static final String KEY_ROWID = "rowid";
5659

57-
private static SQLiteDatabase database;
58-
private static LeanplumDataBaseManager databaseManager;
59-
private static ContentValues contentValues = new ContentValues();
60+
private SQLiteDatabase database;
61+
private LeanplumDataBaseManager databaseManager;
62+
private ContentValues contentValues = new ContentValues();
63+
private boolean sendErrorLogs = false;
6064

61-
static boolean willSendErrorLog = false;
65+
private LeanplumEventDataManager() {
66+
try {
67+
Context context = Leanplum.getContext();
6268

63-
/**
64-
* Creates connection to database, if database is not present, it will automatically create it.
65-
*
66-
* @param context Current context.
67-
*/
68-
public static void init(Context context) {
69-
if (database != null) {
70-
Log.e("Database is already initialized.");
71-
return;
72-
}
69+
if (context == null) {
70+
return;
71+
}
7372

74-
// Create database if needed.
75-
try {
7673
if (databaseManager == null) {
77-
databaseManager = new LeanplumDataBaseManager(context);
74+
databaseManager = new LeanplumDataBaseManager(Leanplum.getContext());
7875
}
7976
database = databaseManager.getWritableDatabase();
77+
8078
} catch (Throwable t) {
8179
handleSQLiteError("Cannot create database.", t);
8280
}
8381
}
8482

83+
public static LeanplumEventDataManager sharedInstance() {
84+
if (instance == null) {
85+
instance = new LeanplumEventDataManager();
86+
}
87+
return instance;
88+
}
89+
8590
/**
8691
* Inserts event to event table.
8792
*
8893
* @param event String with json of event.
8994
*/
90-
static void insertEvent(String event) {
95+
void insertEvent(String event) {
9196
if (database == null) {
9297
return;
9398
}
9499
contentValues.put(COLUMN_DATA, event);
95100
try {
96101
database.insert(EVENT_TABLE_NAME, null, contentValues);
97-
willSendErrorLog = false;
102+
sendErrorLogs = false;
98103
} catch (Throwable t) {
99104
handleSQLiteError("Unable to insert event to database.", t);
100105
}
@@ -108,7 +113,7 @@ static void insertEvent(String event) {
108113
* @param count Number of events.
109114
* @return List of events.
110115
*/
111-
static List<Map<String, Object>> getEvents(int count) {
116+
List<Map<String, Object>> getEvents(int count) {
112117
List<Map<String, Object>> events = new ArrayList<>();
113118
if (database == null) {
114119
return events;
@@ -117,7 +122,7 @@ static List<Map<String, Object>> getEvents(int count) {
117122
try {
118123
cursor = database.query(EVENT_TABLE_NAME, new String[] {COLUMN_DATA}, null, null, null,
119124
null, KEY_ROWID + " ASC", "" + count);
120-
willSendErrorLog = false;
125+
sendErrorLogs = false;
121126
while (cursor.moveToNext()) {
122127
Map<String, Object> requestArgs = JsonConverter.mapFromJson(new JSONObject(
123128
cursor.getString(cursor.getColumnIndex(COLUMN_DATA))));
@@ -139,14 +144,14 @@ static List<Map<String, Object>> getEvents(int count) {
139144
*
140145
* @param count Number of event that need to be deleted.
141146
*/
142-
static void deleteEvents(int count) {
147+
void deleteEvents(int count) {
143148
if (database == null) {
144149
return;
145150
}
146151
try {
147152
database.delete(EVENT_TABLE_NAME, KEY_ROWID + " in (select " + KEY_ROWID + " from " +
148153
EVENT_TABLE_NAME + " ORDER BY " + KEY_ROWID + " ASC LIMIT " + count + ")", null);
149-
willSendErrorLog = false;
154+
sendErrorLogs = false;
150155
} catch (Throwable t) {
151156
handleSQLiteError("Unable to delete events from the table.", t);
152157
}
@@ -158,33 +163,41 @@ static void deleteEvents(int count) {
158163
*
159164
* @return Number of rows in the event table.
160165
*/
161-
static long getEventsCount() {
166+
long getEventsCount() {
162167
long count = 0;
163168
if (database == null) {
164169
return count;
165170
}
166171
try {
167172
count = DatabaseUtils.queryNumEntries(database, EVENT_TABLE_NAME);
168-
willSendErrorLog = false;
173+
sendErrorLogs = false;
169174
} catch (Throwable t) {
170175
handleSQLiteError("Unable to get a number of rows in the table.", t);
171176
}
172177
return count;
173178
}
174179

180+
/**
181+
* Whether we are going to send error log or not.
182+
*/
183+
boolean willSendErrorLogs() {
184+
return sendErrorLogs;
185+
}
186+
175187
/**
176188
* Helper function that logs and sends errors to the server.
177189
*/
178-
private static void handleSQLiteError(String log, Throwable t) {
190+
private void handleSQLiteError(String log, Throwable t) {
179191
Log.e(log, t);
180192
// Send error log. Using willSendErrorLog to prevent infinte loop.
181-
if (!willSendErrorLog) {
182-
willSendErrorLog = true;
193+
if (!sendErrorLogs) {
194+
sendErrorLogs = true;
183195
Util.handleException(t);
184196
}
185197
}
186198

187199
private static class LeanplumDataBaseManager extends SQLiteOpenHelper {
200+
188201
LeanplumDataBaseManager(Context context) {
189202
super(context, DATABASE_NAME, null, DATABASE_VERSION);
190203
}
@@ -239,6 +252,8 @@ private static void migrateFromSharedPreferences(SQLiteDatabase db) {
239252

240253
editor.remove(Constants.Defaults.COUNT_KEY);
241254

255+
ContentValues contentValues = new ContentValues();
256+
242257
try {
243258
String uuid = preferences.getString(Constants.Defaults.UUID_KEY, null);
244259
if (uuid == null || count % RequestOld.MAX_EVENTS_PER_API_CALL == 0) {

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

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
import android.content.SharedPreferences;
2626
import android.os.AsyncTask;
2727
import android.os.Build;
28+
import android.os.Looper;
29+
import android.support.annotation.MainThread;
2830
import android.support.annotation.NonNull;
2931
import android.support.annotation.VisibleForTesting;
3032
import android.text.TextUtils;
@@ -215,7 +217,7 @@ public RequestOld(String httpMethod, String apiMethod, Map<String, Object> param
215217
this.apiMethod = apiMethod;
216218
this.params = params != null ? params : new HashMap<String, Object>();
217219
// Check if it is error and here was SQLite exception.
218-
if (Constants.Methods.LOG.equals(apiMethod) && LeanplumEventDataManager.willSendErrorLog) {
220+
if (Constants.Methods.LOG.equals(apiMethod) && LeanplumEventDataManager.sharedInstance().willSendErrorLogs()) {
219221
localErrors.add(createArgsDictionary());
220222
}
221223
// Make sure the Handler is initialized on the main thread.
@@ -274,22 +276,27 @@ public Map<String, Object> createArgsDictionary() {
274276

275277
private void saveRequestForLater(Map<String, Object> args) {
276278
try {
279+
280+
Context context = Leanplum.getContext();
281+
if (context == null) {
282+
return;
283+
}
284+
277285
requestSequenceRecorder.beforeWrite();
278286

279287
synchronized (RequestOld.class) {
280-
Context context = Leanplum.getContext();
281288
SharedPreferences preferences = context.getSharedPreferences(
282289
LEANPLUM, Context.MODE_PRIVATE);
283290
SharedPreferences.Editor editor = preferences.edit();
284-
long count = LeanplumEventDataManager.getEventsCount();
291+
long count = LeanplumEventDataManager.sharedInstance().getEventsCount();
285292
String uuid = preferences.getString(Constants.Defaults.UUID_KEY, null);
286293
if (uuid == null || count % MAX_EVENTS_PER_API_CALL == 0) {
287294
uuid = UUID.randomUUID().toString();
288295
editor.putString(Constants.Defaults.UUID_KEY, uuid);
289296
SharedPreferencesUtil.commitChanges(editor);
290297
}
291298
args.put(UUID_KEY, uuid);
292-
LeanplumEventDataManager.insertEvent(JsonConverter.toJson(args));
299+
LeanplumEventDataManager.sharedInstance().insertEvent(JsonConverter.toJson(args));
293300

294301
dataBaseIndex = count;
295302
// Checks if here response and/or error callback for this request. We need to add callbacks to
@@ -365,9 +372,9 @@ private void sendIfDelayedHelper() {
365372

366373
public void sendIfConnected() {
367374
if (Util.isConnected()) {
368-
this.sendNow();
375+
sendNow();
369376
} else {
370-
this.sendEventually();
377+
sendEventually();
371378
Log.i("Device is offline, will send later");
372379
triggerErrorCallback(new Exception("Not connected to the Internet"));
373380
}
@@ -524,7 +531,6 @@ protected Void doInBackground(Void... params) {
524531
});
525532
}
526533

527-
528534
/**
529535
* This class wraps the unsent requests, requests that we need to send
530536
* and the JSON encoded string. Wrapping it in the class allows us to
@@ -692,7 +698,7 @@ public void sendEventually() {
692698
return;
693699
}
694700

695-
if (LeanplumEventDataManager.willSendErrorLog) {
701+
if (LeanplumEventDataManager.sharedInstance().willSendErrorLogs()) {
696702
return;
697703
}
698704

@@ -709,7 +715,7 @@ static void deleteSentRequests(int requestsCount) {
709715
return;
710716
}
711717
synchronized (RequestOld.class) {
712-
LeanplumEventDataManager.deleteEvents(requestsCount);
718+
LeanplumEventDataManager.sharedInstance().deleteEvents(requestsCount);
713719
}
714720
}
715721

@@ -723,7 +729,7 @@ public List<Map<String, Object>> getUnsentRequests(double fraction) {
723729
LEANPLUM, Context.MODE_PRIVATE);
724730
SharedPreferences.Editor editor = preferences.edit();
725731
int count = (int) (fraction * MAX_EVENTS_PER_API_CALL);
726-
requestData = LeanplumEventDataManager.getEvents(count);
732+
requestData = LeanplumEventDataManager.sharedInstance().getEvents(count);
727733
editor.remove(Constants.Defaults.UUID_KEY);
728734
SharedPreferencesUtil.commitChanges(editor);
729735
// if we send less than 100% of requests, we need to reset the batch

0 commit comments

Comments
 (0)