Skip to content

Commit 89a0bc6

Browse files
committed
Merge branch 'master' into major_release_4.0.0
2 parents bae9ba8 + 3ccd683 commit 89a0bc6

File tree

9 files changed

+134
-57
lines changed

9 files changed

+134
-57
lines changed

OneSignalSDK/onesignal/src/main/java/com/onesignal/ActivityLifecycleHandler.java

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,10 @@ abstract static class ActivityAvailableListener {
5151
void available(@NonNull Activity activity) {
5252
}
5353

54-
void stopped(WeakReference<Activity> reference) {
54+
void stopped() {
55+
}
56+
57+
void lostFocus() {
5558
}
5659
}
5760

@@ -108,7 +111,7 @@ void onActivityStopped(Activity activity) {
108111
}
109112

110113
for (Map.Entry<String, ActivityAvailableListener> entry : sActivityAvailableListeners.entrySet()) {
111-
entry.getValue().stopped(new WeakReference<>(activity));
114+
entry.getValue().stopped();
112115
}
113116

114117
logCurActivity();
@@ -148,7 +151,7 @@ private void onOrientationChanged() {
148151
// Remove view
149152
handleLostFocus();
150153
for (Map.Entry<String, ActivityAvailableListener> entry : sActivityAvailableListeners.entrySet()) {
151-
entry.getValue().stopped(new WeakReference<>(curActivity));
154+
entry.getValue().stopped();
152155
}
153156

154157
// Show view
@@ -295,6 +298,9 @@ public void run() {
295298
return;
296299

297300
backgrounded = true;
301+
for (Map.Entry<String, ActivityAvailableListener> entry : sActivityAvailableListeners.entrySet()) {
302+
entry.getValue().lostFocus();
303+
}
298304
OneSignal.onAppLostFocus();
299305
completed = true;
300306
}

OneSignalSDK/onesignal/src/main/java/com/onesignal/InAppMessageView.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -451,7 +451,6 @@ public void run() {
451451
* IAM has been fully dismissed, remove all views and call the onMessageWasDismissed callback
452452
*/
453453
private void cleanupViewsAfterDismiss() {
454-
OneSignal.onesignalLog(OneSignal.LOG_LEVEL.DEBUG, "InAppMessageView cleanupViewsAfterDismiss");
455454
removeAllViews();
456455
if (messageController != null)
457456
messageController.onMessageWasDismissed();
@@ -461,6 +460,7 @@ private void cleanupViewsAfterDismiss() {
461460
* Remove all views and dismiss PopupWindow
462461
*/
463462
void removeAllViews() {
463+
OneSignal.onesignalLog(OneSignal.LOG_LEVEL.DEBUG, "InAppMessageView removing views");
464464
if (scheduleDismissRunnable != null) {
465465
// Dismissed before the dismiss delay
466466
handler.removeCallbacks(scheduleDismissRunnable);

OneSignalSDK/onesignal/src/main/java/com/onesignal/OSInAppMessageController.java

Lines changed: 39 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
import android.app.AlertDialog;
44
import android.content.DialogInterface;
5-
import android.os.Build;
65
import android.os.Process;
76

87
import androidx.annotation.NonNull;
@@ -26,6 +25,7 @@
2625

2726
class OSInAppMessageController implements OSDynamicTriggerControllerObserver, OSSystemConditionController.OSSystemConditionObserver {
2827

28+
private static final Object LOCK = new Object();
2929
private static final String OS_SAVE_IN_APP_MESSAGE = "OS_SAVE_IN_APP_MESSAGE";
3030
public static final String IN_APP_MESSAGES_JSON_KEY = "in_app_messages";
3131
private static ArrayList<String> PREFERRED_VARIANT_ORDER = new ArrayList<String>() {{
@@ -129,23 +129,31 @@ void resetSessionLaunchTime() {
129129
// however an on session won't happen
130130
void initWithCachedInAppMessages() {
131131
// Do not reload from cache if already loaded.
132-
if (!messages.isEmpty())
132+
if (!messages.isEmpty()) {
133+
OneSignal.Log(OneSignal.LOG_LEVEL.DEBUG, "initWithCachedInAppMessages with already in memory messages: " + messages);
133134
return;
135+
}
134136

135-
String cachedIamsStr = OneSignalPrefs.getString(
137+
String cachedInAppMessageString = OneSignalPrefs.getString(
136138
OneSignalPrefs.PREFS_ONESIGNAL,
137139
OneSignalPrefs.PREFS_OS_CACHED_IAMS,
138140
null
139141
);
140-
OneSignal.Log(OneSignal.LOG_LEVEL.DEBUG, "initWithCachedInAppMessages: " + cachedIamsStr);
142+
OneSignal.Log(OneSignal.LOG_LEVEL.DEBUG, "initWithCachedInAppMessages: " + cachedInAppMessageString);
141143

142-
if (cachedIamsStr == null)
144+
if (cachedInAppMessageString == null || cachedInAppMessageString.isEmpty())
143145
return;
144146

145-
try {
146-
processInAppMessageJson(new JSONArray(cachedIamsStr));
147-
} catch (JSONException e) {
148-
e.printStackTrace();
147+
synchronized (LOCK) {
148+
try {
149+
// Second check to avoid getting the lock while message list is being set
150+
if (!messages.isEmpty())
151+
return;
152+
153+
processInAppMessageJson(new JSONArray(cachedInAppMessageString));
154+
} catch (JSONException e) {
155+
e.printStackTrace();
156+
}
149157
}
150158
}
151159

@@ -171,27 +179,21 @@ private void resetRedisplayMessagesBySession() {
171179
}
172180

173181
private void processInAppMessageJson(@NonNull JSONArray json) throws JSONException {
174-
ArrayList<OSInAppMessage> newMessages = new ArrayList<>();
175-
for (int i = 0; i < json.length(); i++) {
176-
JSONObject messageJson = json.getJSONObject(i);
177-
OSInAppMessage message = new OSInAppMessage(messageJson);
182+
synchronized (LOCK) {
183+
ArrayList<OSInAppMessage> newMessages = new ArrayList<>();
184+
for (int i = 0; i < json.length(); i++) {
185+
JSONObject messageJson = json.getJSONObject(i);
186+
OSInAppMessage message = new OSInAppMessage(messageJson);
187+
188+
newMessages.add(message);
189+
}
178190

179-
populateRedisplayMessageTriggers(message);
180-
newMessages.add(message);
191+
messages = newMessages;
181192
}
182-
messages = newMessages;
183193

184194
evaluateInAppMessages();
185195
}
186196

187-
private void populateRedisplayMessageTriggers(OSInAppMessage message) {
188-
int index = redisplayedInAppMessages.indexOf(message);
189-
if (index > -1) {
190-
OSInAppMessage redisplayMessage = redisplayedInAppMessages.get(index);
191-
redisplayMessage.triggers = message.triggers;
192-
}
193-
}
194-
195197
private void evaluateInAppMessages() {
196198
OneSignal.Log(OneSignal.LOG_LEVEL.DEBUG, "Starting evaluateInAppMessages");
197199

@@ -480,7 +482,7 @@ private void setDataForRedisplay(OSInAppMessage message) {
480482
message.getRedisplayStats().setDisplayStats(savedIAM.getRedisplayStats());
481483

482484
// Message that don't have triggers should display only once per session
483-
boolean triggerHasChanged = savedIAM.isTriggerChanged() || (!savedIAM.isDisplayedInSession() && message.triggers.isEmpty());
485+
boolean triggerHasChanged = message.isTriggerChanged() || (!savedIAM.isDisplayedInSession() && message.triggers.isEmpty());
484486

485487
OneSignal.onesignalLog(OneSignal.LOG_LEVEL.DEBUG, "setDataForRedisplay: " + message.toString() + " triggerHasChanged: " + triggerHasChanged);
486488

@@ -551,9 +553,6 @@ void messageWasDismissed(@NonNull OSInAppMessage message) {
551553
}
552554

553555
void messageWasDismissed(@NonNull OSInAppMessage message, boolean failed) {
554-
// Remove DIRECT influence due to ClickHandler of ClickAction outcomes
555-
OneSignal.getSessionManager().onDirectInfluenceFromIAMClickFinished();
556-
557556
if (!message.isPreview) {
558557
dismissedMessages.add(message.messageId);
559558
// If failed we will retry on next session
@@ -574,12 +573,21 @@ void messageWasDismissed(@NonNull OSInAppMessage message, boolean failed) {
574573
dismissCurrentMessage(message);
575574
}
576575

576+
void messageWasDismissedByBackPress(@NonNull OSInAppMessage message) {
577+
OneSignal.onesignalLog(OneSignal.LOG_LEVEL.DEBUG, "OSInAppMessageController messageWasDismissed by back press: " + message.toString());
578+
// IAM was not dismissed by user, will be redisplay again until user dismiss it
579+
dismissCurrentMessage(message);
580+
}
581+
577582
/**
578583
* Removes first item from the queue and attempts to show the next IAM in the queue
579584
*
580585
* @param message The message dismissed, preview messages are null
581586
*/
582587
private void dismissCurrentMessage(@Nullable OSInAppMessage message) {
588+
// Remove DIRECT influence due to ClickHandler of ClickAction outcomes
589+
OneSignal.getSessionManager().onDirectInfluenceFromIAMClickFinished();
590+
583591
if (currentPrompt != null) {
584592
logger.debug("Stop evaluateMessageDisplayQueue because prompt is currently displayed");
585593
return;
@@ -781,8 +789,9 @@ public void systemConditionChanged() {
781789
* - At least one Trigger has changed
782790
*/
783791
private void makeRedisplayMessagesAvailableWithTriggers(Collection<String> newTriggersKeys) {
784-
for (OSInAppMessage message : redisplayedInAppMessages) {
785-
if (!message.isTriggerChanged() && triggerController.isTriggerOnMessage(message, newTriggersKeys)) {
792+
for (OSInAppMessage message : messages) {
793+
if (!message.isTriggerChanged() && redisplayedInAppMessages.contains(message) &&
794+
triggerController.isTriggerOnMessage(message, newTriggersKeys)) {
786795
logger.debug("Trigger changed for message: " + message.toString());
787796
message.setTriggerChanged(true);
788797
}

OneSignalSDK/onesignal/src/main/java/com/onesignal/OSTriggerController.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,9 @@ private boolean triggerMatchesNumericValue(@NonNull Number triggerValue, @NonNul
181181
* If trigger key is part of message triggers, then return true, otherwise false
182182
* */
183183
boolean isTriggerOnMessage(OSInAppMessage message, Collection<String> newTriggersKeys) {
184+
if (message.triggers == null)
185+
return false;
186+
184187
for (String triggerKey : newTriggersKeys) {
185188
for (ArrayList<OSTrigger> andConditions : message.triggers) {
186189
for (OSTrigger trigger : andConditions) {

OneSignalSDK/onesignal/src/main/java/com/onesignal/OneSignal.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -803,16 +803,18 @@ private static void handleAmazonPurchase() {
803803
private static void doSessionInit() {
804804
// Check session time to determine whether to start a new session or not
805805
if (isPastOnSessionTime()) {
806-
OneSignalStateSynchronizer.setNewSession();
806+
OneSignal.onesignalLog(LOG_LEVEL.DEBUG, "Starting new session");
807+
OneSignalStateSynchronizer.setNewSession();
807808
if (inForeground) {
808809
outcomeEventsController.cleanOutcomes();
809810
sessionManager.restartSessionIfNeeded(getAppEntryState());
810811
getInAppMessageController().resetSessionLaunchTime();
811812
}
812813
} else if (inForeground) {
813-
getInAppMessageController().initWithCachedInAppMessages();
814+
OneSignal.onesignalLog(LOG_LEVEL.DEBUG, "Continue on same session");
814815
sessionManager.attemptSessionUpgrade(getAppEntryState());
815816
}
817+
getInAppMessageController().initWithCachedInAppMessages();
816818

817819
// We still want register the user to OneSignal if the SDK was initialized
818820
// in the background for the first time.

OneSignalSDK/onesignal/src/main/java/com/onesignal/OneSignalDbHelper.java

Lines changed: 36 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -207,11 +207,19 @@ public void insert(@NonNull String table, @Nullable String nullColumnHack, @Null
207207
writableDb.beginTransaction();
208208
writableDb.insert(table, nullColumnHack, values);
209209
writableDb.setTransactionSuccessful();
210+
} catch (SQLiteException e) {
211+
logger.error("Error inserting on table: " + table + " with nullColumnHack: " + nullColumnHack + " and values: " + values, e);
212+
} catch (IllegalStateException e) {
213+
logger.error("Error under inserting transaction under table: " + table + " with nullColumnHack: " + nullColumnHack + " and values: " + values, e);
210214
} finally {
211-
try {
212-
writableDb.endTransaction(); // May throw if transaction was never opened or DB is full.
213-
} catch (SQLException e) {
214-
logger.error("Error closing transaction! ", e);
215+
if (writableDb != null) {
216+
try {
217+
writableDb.endTransaction(); // May throw if transaction was never opened or DB is full.
218+
} catch (IllegalStateException e) {
219+
logger.error("Error closing transaction! ", e);
220+
} catch (SQLiteException e) {
221+
logger.error("Error closing transaction! ", e);
222+
}
215223
}
216224
}
217225
}
@@ -226,14 +234,18 @@ public void insertOrThrow(@NonNull String table, @Nullable String nullColumnHack
226234
writableDb.beginTransaction();
227235
writableDb.insertOrThrow(table, nullColumnHack, values);
228236
writableDb.setTransactionSuccessful();
229-
} catch (Throwable t) {
230-
OneSignal.Log(OneSignal.LOG_LEVEL.ERROR, "Error inserting under table: " + table, t);
237+
} catch (SQLiteException e) {
238+
logger.error("Error inserting or throw on table: " + table + " with nullColumnHack: " + nullColumnHack + " and values: " + values, e);
239+
} catch (IllegalStateException e) {
240+
logger.error("Error under inserting or throw transaction under table: " + table + " with nullColumnHack: " + nullColumnHack + " and values: " + values, e);
231241
} finally {
232242
if (writableDb != null) {
233243
try {
234244
writableDb.endTransaction(); // May throw if transaction was never opened or DB is full.
235-
} catch (Throwable t) {
236-
OneSignal.Log(OneSignal.LOG_LEVEL.ERROR, "Error closing transaction! ", t);
245+
} catch (IllegalStateException e) {
246+
logger.error("Error closing transaction! ", e);
247+
} catch (SQLiteException e) {
248+
logger.error("Error closing transaction! ", e);
237249
}
238250
}
239251
}
@@ -243,20 +255,27 @@ public void insertOrThrow(@NonNull String table, @Nullable String nullColumnHack
243255
@Override
244256
public int update(@NonNull String table, @NonNull ContentValues values, @Nullable String whereClause, @Nullable String[] whereArgs) {
245257
int result = 0;
258+
if (values == null || values.toString().isEmpty())
259+
return result;
260+
246261
synchronized (LOCK) {
247262
SQLiteDatabase writableDb = getSQLiteDatabaseWithRetries();
248263
try {
249264
writableDb.beginTransaction();
250265
result = writableDb.update(table, values, whereClause, whereArgs);
251266
writableDb.setTransactionSuccessful();
252-
} catch (Throwable t) {
253-
OneSignal.Log(OneSignal.LOG_LEVEL.ERROR, "Error updating table: " + table, t);
267+
} catch (SQLiteException e) {
268+
logger.error("Error updating on table: " + table + " with whereClause: " + whereClause + " and whereArgs: " + whereArgs, e);
269+
} catch (IllegalStateException e) {
270+
logger.error("Error under update transaction under table: " + table + " with whereClause: " + whereClause + " and whereArgs: " + whereArgs, e);
254271
} finally {
255272
if (writableDb != null) {
256273
try {
257274
writableDb.endTransaction(); // May throw if transaction was never opened or DB is full.
258-
} catch (Throwable t) {
259-
OneSignal.Log(OneSignal.LOG_LEVEL.ERROR, "Error closing transaction! ", t);
275+
} catch (IllegalStateException e) {
276+
logger.error("Error closing transaction! ", e);
277+
} catch (SQLiteException e) {
278+
logger.error("Error closing transaction! ", e);
260279
}
261280
}
262281
}
@@ -273,11 +292,15 @@ public void delete(@NonNull String table, @Nullable String whereClause, @Nullabl
273292
writableDb.delete(table, whereClause, whereArgs);
274293
writableDb.setTransactionSuccessful();
275294
} catch (SQLiteException e) {
276-
logger.error("Error deleting on table: " + table, e);
295+
logger.error("Error deleting on table: " + table + " with whereClause: " + whereClause + " and whereArgs: " + whereArgs, e);
296+
} catch (IllegalStateException e) {
297+
logger.error("Error under delete transaction under table: " + table + " with whereClause: " + whereClause + " and whereArgs: " + whereArgs, e);
277298
} finally {
278299
if (writableDb != null) {
279300
try {
280301
writableDb.endTransaction(); // May throw if transaction was never opened or DB is full.
302+
} catch (IllegalStateException e) {
303+
logger.error("Error closing transaction! ", e);
281304
} catch (SQLiteException e) {
282305
logger.error("Error closing transaction! ", e);
283306
}

0 commit comments

Comments
 (0)