Skip to content

Commit 94a71a5

Browse files
committed
Display once per session IAM with redisplay
* Add no trigger check, display once per session * Add displayed param to IAM * Add test for cold start and init OneSignal
1 parent c6c0a32 commit 94a71a5

File tree

10 files changed

+115
-20
lines changed

10 files changed

+115
-20
lines changed

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

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ class OSInAppMessage {
5454
private OSInAppMessageDisplayStats displayStats = new OSInAppMessageDisplayStats();
5555

5656
private double displayDuration;
57+
private boolean displayedInSession = false;
5758
private boolean triggerChanged = false;
5859
private boolean actionTaken;
5960
boolean isPreview;
@@ -62,15 +63,14 @@ class OSInAppMessage {
6263
this.isPreview = isPreview;
6364
}
6465

65-
OSInAppMessage(@NonNull String messageId, @NonNull Set<String> clickIds, OSInAppMessageDisplayStats displayStats) {
66+
OSInAppMessage(@NonNull String messageId, @NonNull Set<String> clickIds, boolean displayedInSession, OSInAppMessageDisplayStats displayStats) {
6667
this.messageId = messageId;
6768
this.clickedClickIds = clickIds;
68-
69+
this.displayedInSession = displayedInSession;
6970
this.displayStats = displayStats;
7071
}
7172

7273
OSInAppMessage(JSONObject json) throws JSONException {
73-
7474
// initialize simple root properties
7575
this.messageId = json.getString(IAM_ID);
7676
this.variants = parseVariants(json.getJSONObject(IAM_VARIANTS));
@@ -189,6 +189,14 @@ void setTriggerChanged(boolean triggerChanged) {
189189
this.triggerChanged = triggerChanged;
190190
}
191191

192+
public boolean isDisplayedInSession() {
193+
return displayedInSession;
194+
}
195+
196+
public void setDisplayedInSession(boolean displayedInSession) {
197+
this.displayedInSession = displayedInSession;
198+
}
199+
192200
@NonNull
193201
Set<String> getClickedClickIds() {
194202
return clickedClickIds;

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

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -152,16 +152,15 @@ void receivedInAppMessageJson(@NonNull JSONArray json) throws JSONException {
152152
OneSignalPrefs.PREFS_OS_CACHED_IAMS,
153153
json.toString());
154154

155+
resetRedisplayMessagesBySession();
155156
processInAppMessageJson(json);
157+
deleteOldRedisplayedInAppMessages();
158+
}
156159

157-
// Remove cache redisplayed messages
158-
new Thread(new Runnable() {
159-
@Override
160-
public void run() {
161-
Thread.currentThread().setPriority(Process.THREAD_PRIORITY_BACKGROUND);
162-
inAppMessageRepository.deleteOldRedisplayedInAppMessages();
163-
}
164-
}, OS_DELETE_IN_APP_MESSAGE).start();
160+
private void resetRedisplayMessagesBySession() {
161+
for (OSInAppMessage redisplayInAppMessage : redisplayedInAppMessages) {
162+
redisplayInAppMessage.setDisplayedInSession(false);
163+
}
165164
}
166165

167166
private void processInAppMessageJson(@NonNull JSONArray json) throws JSONException {
@@ -176,6 +175,16 @@ private void processInAppMessageJson(@NonNull JSONArray json) throws JSONExcepti
176175
evaluateInAppMessages();
177176
}
178177

178+
private void deleteOldRedisplayedInAppMessages() {
179+
new Thread(new Runnable() {
180+
@Override
181+
public void run() {
182+
Thread.currentThread().setPriority(Process.THREAD_PRIORITY_BACKGROUND);
183+
inAppMessageRepository.deleteOldRedisplayedInAppMessages();
184+
}
185+
}, OS_DELETE_IN_APP_MESSAGE).start();
186+
}
187+
179188
private void evaluateInAppMessages() {
180189
if (systemConditionController.systemConditionsAvailable()) {
181190
for (OSInAppMessage message : messages) {
@@ -373,8 +382,10 @@ private void setDataForRedisplay(OSInAppMessage message) {
373382
OSInAppMessage savedIAM = redisplayedInAppMessages.get(index);
374383
message.getDisplayStats().setDisplayStats(savedIAM.getDisplayStats());
375384

385+
// Message that don't have triggers should display only once per session
386+
boolean triggerHasChanged = message.isTriggerChanged() || (!savedIAM.isDisplayedInSession() && message.triggers.isEmpty());
376387
// Check if conditions are correct for redisplay
377-
if (message.isTriggerChanged() &&
388+
if (triggerHasChanged &&
378389
message.getDisplayStats().isDelayTimeSatisfied() &&
379390
message.getDisplayStats().shouldDisplayAgain()) {
380391
dismissedMessages.remove(message.messageId);
@@ -478,6 +489,7 @@ private void persistInAppMessageForRedisplay(final OSInAppMessage message) {
478489
message.getDisplayStats().setLastDisplayTime(displayTimeSeconds);
479490
message.getDisplayStats().incrementDisplayQuantity();
480491
message.setTriggerChanged(false);
492+
message.setDisplayedInSession(true);
481493

482494
new Thread(new Runnable() {
483495
@Override

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ synchronized void saveInAppMessage(OSInAppMessage inAppMessage) {
4646
values.put(OneSignalDbContract.InAppMessageTable.COLUMN_NAME_DISPLAY_QUANTITY, inAppMessage.getDisplayStats().getDisplayQuantity());
4747
values.put(OneSignalDbContract.InAppMessageTable.COLUMN_NAME_LAST_DISPLAY, inAppMessage.getDisplayStats().getLastDisplayTime());
4848
values.put(OneSignalDbContract.InAppMessageTable.COLUMN_CLICK_IDS, inAppMessage.getClickedClickIds().toString());
49+
values.put(OneSignalDbContract.InAppMessageTable.COLUMN_DISPLAYED_IN_SESSION, inAppMessage.isDisplayedInSession());
4950

5051
int rowsUpdated = writableDb.update(OneSignalDbContract.InAppMessageTable.TABLE_NAME, values,
5152
OneSignalDbContract.InAppMessageTable.COLUMN_NAME_MESSAGE_ID + " = ?", new String[]{inAppMessage.messageId});
@@ -77,6 +78,7 @@ synchronized List<OSInAppMessage> getRedisplayedInAppMessages() {
7778
String clickIds = cursor.getString(cursor.getColumnIndex(OneSignalDbContract.InAppMessageTable.COLUMN_CLICK_IDS));
7879
int displayQuantity = cursor.getInt(cursor.getColumnIndex(OneSignalDbContract.InAppMessageTable.COLUMN_NAME_DISPLAY_QUANTITY));
7980
long lastDisplay = cursor.getLong(cursor.getColumnIndex(OneSignalDbContract.InAppMessageTable.COLUMN_NAME_LAST_DISPLAY));
81+
boolean displayed = cursor.getInt(cursor.getColumnIndex(OneSignalDbContract.InAppMessageTable.COLUMN_DISPLAYED_IN_SESSION)) == 1;
8082

8183
JSONArray clickIdsArray = new JSONArray(clickIds);
8284
Set<String> clickIdsSet = new HashSet<>();
@@ -85,7 +87,7 @@ synchronized List<OSInAppMessage> getRedisplayedInAppMessages() {
8587
clickIdsSet.add(clickIdsArray.getString(i));
8688
}
8789

88-
OSInAppMessage inAppMessage = new OSInAppMessage(messageId, clickIdsSet, new OSInAppMessageDisplayStats(displayQuantity, lastDisplay));
90+
OSInAppMessage inAppMessage = new OSInAppMessage(messageId, clickIdsSet, displayed, new OSInAppMessageDisplayStats(displayQuantity, lastDisplay));
8991
iams.add(inAppMessage);
9092
} while (cursor.moveToNext());
9193
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,5 +81,6 @@ static abstract class InAppMessageTable implements BaseColumns {
8181
public static final String COLUMN_NAME_DISPLAY_QUANTITY = "display_quantity";
8282
public static final String COLUMN_NAME_LAST_DISPLAY = "last_display";
8383
public static final String COLUMN_CLICK_IDS = "click_ids";
84+
public static final String COLUMN_DISPLAYED_IN_SESSION = "displayed_in_session";
8485
}
8586
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ public class OneSignalDbHelper extends SQLiteOpenHelper {
9797
InAppMessageTable.COLUMN_NAME_DISPLAY_QUANTITY + INT_TYPE + COMMA_SEP +
9898
InAppMessageTable.COLUMN_NAME_LAST_DISPLAY + INT_TYPE + COMMA_SEP +
9999
InAppMessageTable.COLUMN_NAME_MESSAGE_ID + TEXT_TYPE + COMMA_SEP +
100+
InAppMessageTable.COLUMN_DISPLAYED_IN_SESSION + INT_TYPE + COMMA_SEP +
100101
InAppMessageTable.COLUMN_CLICK_IDS + TEXT_TYPE +
101102
");";
102103

OneSignalSDK/unittest/src/test/java/com/onesignal/OneSignalPackagePrivateHelper.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -272,8 +272,8 @@ public class OneSignalDbContract extends com.onesignal.OneSignalDbContract {}
272272

273273
public static class OSTestInAppMessage extends com.onesignal.OSInAppMessage {
274274

275-
public OSTestInAppMessage(@NonNull String messageId, int displaysQuantity, long lastDisplayTime, Set<String> clickIds) {
276-
super(messageId, clickIds, new OSInAppMessageDisplayStats(displaysQuantity, lastDisplayTime));
275+
public OSTestInAppMessage(@NonNull String messageId, int displaysQuantity, long lastDisplayTime, boolean displayed, Set<String> clickIds) {
276+
super(messageId, clickIds, displayed, new OSInAppMessageDisplayStats(displaysQuantity, lastDisplayTime));
277277
}
278278

279279
OSTestInAppMessage(JSONObject json) throws JSONException {
@@ -371,6 +371,10 @@ public void setLastDisplayTime(long lastDisplayTime) {
371371
this.displayStats.setLastDisplayTime(lastDisplayTime);
372372
}
373373

374+
public void setLastDisplayTimeToCurrent() {
375+
this.displayStats.setLastDisplayTime(System.currentTimeMillis() / 1000);
376+
}
377+
374378
@Override
375379
public void incrementDisplayQuantity() {
376380
this.displayStats.incrementDisplayQuantity();

OneSignalSDK/unittest/src/test/java/com/test/onesignal/DatabaseRunner.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,11 +271,14 @@ public void shouldUpgradeDbFromV6ToV7() throws JSONException {
271271
OneSignalPackagePrivateHelper.OSTestTrigger.OSTriggerOperator.NOT_EXISTS.toString(),
272272
null);
273273

274+
inAppMessage.setDisplayedInSession(true);
275+
274276
ContentValues values = new ContentValues();
275277
values.put(InAppMessageTable.COLUMN_NAME_MESSAGE_ID, inAppMessage.messageId);
276278
values.put(InAppMessageTable.COLUMN_NAME_DISPLAY_QUANTITY, inAppMessage.getDisplayStats().getDisplayQuantity());
277279
values.put(InAppMessageTable.COLUMN_NAME_LAST_DISPLAY, inAppMessage.getDisplayStats().getLastDisplayTime());
278280
values.put(InAppMessageTable.COLUMN_CLICK_IDS, inAppMessage.getClickedClickIds().toString());
281+
values.put(InAppMessageTable.COLUMN_DISPLAYED_IN_SESSION, inAppMessage.isDisplayedInSession());
279282

280283
// 3. Clear the cache of the DB so it reloads the file.
281284
ShadowOneSignalDbHelper.restSetStaticFields();
@@ -294,5 +297,10 @@ public void shouldUpgradeDbFromV6ToV7() throws JSONException {
294297
List<OSTestInAppMessage> savedInAppMessagesAfterCreation = TestHelpers.getAllInAppMessages();
295298

296299
assertEquals(savedInAppMessagesAfterCreation.size(), 1);
300+
OSTestInAppMessage savedInAppMessage = savedInAppMessagesAfterCreation.get(0);
301+
assertEquals(savedInAppMessage.getDisplayStats().getDisplayQuantity(), inAppMessage.getDisplayStats().getDisplayQuantity());
302+
assertEquals(savedInAppMessage.getDisplayStats().getLastDisplayTime(), inAppMessage.getDisplayStats().getLastDisplayTime());
303+
assertEquals(savedInAppMessage.getClickedClickIds().toString(), inAppMessage.getClickedClickIds().toString());
304+
assertEquals(savedInAppMessage.isDisplayedInSession(), inAppMessage.isDisplayedInSession());
297305
}
298306
}

OneSignalSDK/unittest/src/test/java/com/test/onesignal/InAppMessageIntegrationTests.java

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import com.onesignal.OneSignalPackagePrivateHelper.OSInAppMessageController;
1010
import com.onesignal.OneSignalPackagePrivateHelper.OSTestInAppMessage;
1111
import com.onesignal.OneSignalPackagePrivateHelper.OSTestTrigger;
12+
import com.onesignal.OneSignalPackagePrivateHelper.OneSignalPrefs;
1213
import com.onesignal.ShadowAdvertisingIdProviderGPS;
1314
import com.onesignal.ShadowCustomTabsClient;
1415
import com.onesignal.ShadowCustomTabsSession;
@@ -43,7 +44,9 @@
4344

4445
import java.lang.reflect.Field;
4546
import java.util.ArrayList;
47+
import java.util.Collections;
4648
import java.util.HashMap;
49+
import java.util.HashSet;
4750
import java.util.List;
4851
import java.util.Set;
4952
import java.util.concurrent.Callable;
@@ -77,7 +80,6 @@
7780

7881
@RunWith(RobolectricTestRunner.class)
7982
public class InAppMessageIntegrationTests {
80-
8183
private static final String IAM_CLICK_ID = "button_id_123";
8284
private static final String ONESIGNAL_APP_ID = "b2f7f966-d8cc-11e4-bed1-df8f05be55ba";
8385
private static final long SIX_MONTHS_TIME_SECONDS = 6 * 30 * 24 * 60 * 60;
@@ -625,6 +627,59 @@ public void testInAppMessageDisplayMultipleTimes() throws Exception {
625627
assertTrue(ShadowOSInAppMessageController.dismissedMessages.get(1).getDisplayStats().getLastDisplayTime() - lastDisplayTime == DELAY);
626628
}
627629

630+
@Test
631+
public void testInAppMessageDisplayMultipleTimes_NoTriggers() throws Exception {
632+
final long currentTimeInSeconds = System.currentTimeMillis() / 1000;
633+
634+
// Create an IAM
635+
final OSTestInAppMessage message = InAppMessagingHelpers.buildTestMessageWitRedisplay(LIMIT, DELAY);
636+
message.getDisplayStats().setLastDisplayTime(currentTimeInSeconds);
637+
message.getDisplayStats().setDisplayQuantity(1);
638+
message.setDisplayedInSession(true);
639+
TestHelpers.saveIAM(message);
640+
641+
// Save IAM for dismiss
642+
OneSignalPrefs.saveStringSet(
643+
OneSignalPrefs.PREFS_ONESIGNAL,
644+
OneSignalPrefs.PREFS_OS_DISPLAYED_IAMS,
645+
new HashSet<>(Collections.singletonList(message.messageId))
646+
);
647+
648+
List<OSTestInAppMessage> savedInAppMessages = TestHelpers.getAllInAppMessages();
649+
assertEquals(savedInAppMessages.size(), 1);
650+
assertTrue(savedInAppMessages.get(0).isDisplayedInSession());
651+
652+
setMockRegistrationResponseWithMessages(new ArrayList<OSTestInAppMessage>() {{
653+
add(message);
654+
}});
655+
656+
advanceSystemTimeBy(DELAY);
657+
658+
// Init OneSignal with IAM with redisplay
659+
OneSignalInit();
660+
threadAndTaskWait();
661+
662+
// First init will start a new session, then the IAM should be shown
663+
assertEquals(1, ShadowOSInAppMessageController.displayedMessages.size());
664+
665+
// Dismiss IAM will make display quantity increase and last display time to change
666+
OneSignalPackagePrivateHelper.dismissCurrentMessage();
667+
668+
fastColdRestartApp();
669+
setMockRegistrationResponseWithMessages(new ArrayList<OSTestInAppMessage>() {{
670+
add(message);
671+
}});
672+
OneSignalInit();
673+
threadAndTaskWait();
674+
675+
// Wait for the delay between redisplay
676+
advanceSystemTimeBy(DELAY * 2);
677+
// Add trigger to call evaluateInAppMessage
678+
OneSignal.addTrigger("test_1", 2);
679+
// IAM shouldn't display again because It don't have triggers
680+
assertEquals(1, ShadowOSInAppMessageController.displayedMessages.size());
681+
}
682+
628683
@Test
629684
public void testInAppMessageDisplayMultipleTimes_RemoveTrigger() throws Exception {
630685
final OSTestInAppMessage message = InAppMessagingHelpers.buildTestMessageWithSingleTriggerAndRedisplay(

OneSignalSDK/unittest/src/test/java/com/test/onesignal/InAppMessagingUnitTests.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444

4545
import static com.onesignal.OneSignalPackagePrivateHelper.OSTestTrigger.OSTriggerKind;
4646
import static com.onesignal.OneSignalPackagePrivateHelper.OSTestTrigger.OSTriggerOperator;
47+
import static com.test.onesignal.TestHelpers.advanceSystemTimeBy;
4748
import static com.test.onesignal.TestHelpers.assertMainThread;
4849
import static com.test.onesignal.TestHelpers.threadAndTaskWait;
4950
import static junit.framework.Assert.assertEquals;
@@ -204,12 +205,13 @@ public void testBuiltMessageRedisplayDelay() throws JSONException {
204205
);
205206

206207
assertTrue(message.getDisplayStats().isDelayTimeSatisfied());
207-
final long currentTimeInSeconds = System.currentTimeMillis() / 1000;
208208

209-
message.getDisplayStats().setLastDisplayTime(currentTimeInSeconds - DELAY);
209+
message.getDisplayStats().setLastDisplayTimeToCurrent();
210+
advanceSystemTimeBy(DELAY);
210211
assertTrue(message.getDisplayStats().isDelayTimeSatisfied());
211212

212-
message.getDisplayStats().setLastDisplayTime(currentTimeInSeconds - DELAY + 1);
213+
message.getDisplayStats().setLastDisplayTimeToCurrent();
214+
advanceSystemTimeBy(DELAY - 1);
213215
assertFalse(message.getDisplayStats().isDelayTimeSatisfied());
214216
}
215217

OneSignalSDK/unittest/src/test/java/com/test/onesignal/TestHelpers.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,7 @@ synchronized static void saveIAM(OSTestInAppMessage inAppMessage) {
346346
values.put(OneSignalPackagePrivateHelper.InAppMessageTable.COLUMN_NAME_DISPLAY_QUANTITY, inAppMessage.getDisplayStats().getDisplayQuantity());
347347
values.put(OneSignalPackagePrivateHelper.InAppMessageTable.COLUMN_NAME_LAST_DISPLAY, inAppMessage.getDisplayStats().getLastDisplayTime());
348348
values.put(OneSignalPackagePrivateHelper.InAppMessageTable.COLUMN_CLICK_IDS, inAppMessage.getClickedClickIds().toString());
349+
values.put(OneSignalPackagePrivateHelper.InAppMessageTable.COLUMN_DISPLAYED_IN_SESSION, inAppMessage.isDisplayedInSession());
349350

350351
writableDatabase.insert(OneSignalPackagePrivateHelper.InAppMessageTable.TABLE_NAME, null, values);
351352
writableDatabase.close();
@@ -370,6 +371,7 @@ synchronized static List<OSTestInAppMessage> getAllInAppMessages() throws JSONEx
370371
String clickIds = cursor.getString(cursor.getColumnIndex(OneSignalPackagePrivateHelper.InAppMessageTable.COLUMN_CLICK_IDS));
371372
int displayQuantity = cursor.getInt(cursor.getColumnIndex(OneSignalPackagePrivateHelper.InAppMessageTable.COLUMN_NAME_DISPLAY_QUANTITY));
372373
long lastDisplay = cursor.getLong(cursor.getColumnIndex(OneSignalPackagePrivateHelper.InAppMessageTable.COLUMN_NAME_LAST_DISPLAY));
374+
boolean displayed = cursor.getInt(cursor.getColumnIndex(OneSignalPackagePrivateHelper.InAppMessageTable.COLUMN_DISPLAYED_IN_SESSION)) == 1;
373375

374376
JSONArray clickIdsArray = new JSONArray(clickIds);
375377
Set<String> clickIdsSet = new HashSet<>();
@@ -378,7 +380,7 @@ synchronized static List<OSTestInAppMessage> getAllInAppMessages() throws JSONEx
378380
clickIdsSet.add(clickIdsArray.getString(i));
379381
}
380382

381-
OSTestInAppMessage inAppMessage = new OSTestInAppMessage(messageId, displayQuantity, lastDisplay, clickIdsSet);
383+
OSTestInAppMessage inAppMessage = new OSTestInAppMessage(messageId, displayQuantity, lastDisplay, displayed, clickIdsSet);
382384
iams.add(inAppMessage);
383385
} while (cursor.moveToNext());
384386
}

0 commit comments

Comments
 (0)