Skip to content

Commit 33c17e2

Browse files
committed
Refactor outcomes and add IAM tracking
* Add new package privacy level for outcomes * Add wrappers for static access * Add OutcomesEventsFactory to decide which repository to use * Add new outcome models given the new feature IAM v2 Outcomes * Add concepts of channels and influence * Add IAM tracking for indirect and direct influence * Add ability for future channels * Decouple influence tracking module to new package * Several changes for decouple code for future dependency injection * Add testing to new functionality * Add testing for IAM tracking * Add/Refactor to test with mocks * Add testing for session ending * Add testing for V2 measure
1 parent 21054d3 commit 33c17e2

File tree

83 files changed

+6825
-2053
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

83 files changed

+6825
-2053
lines changed

OneSignalSDK/app/src/main/java/com/onesignal/MainActivity.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
import com.onesignal.example.R;
5252
import com.onesignal.example.iap.IabHelper;
5353
import com.onesignal.example.iap.IabResult;
54+
import com.onesignal.outcomes.model.OSOutcomeEventParams;
5455

5556
import org.json.JSONException;
5657
import org.json.JSONObject;
@@ -370,7 +371,7 @@ public void onFailure(OneSignal.EmailUpdateError error) {
370371
public void onSendOutcomeClicked(View view) {
371372
OneSignal.sendOutcome(outcomeName.getText().toString(), new OneSignal.OutcomeCallback() {
372373
@Override
373-
public void onSuccess(@Nullable OutcomeEvent outcomeEvent) {
374+
public void onSuccess(@Nullable OSOutcomeEventParams outcomeEvent) {
374375
if (outcomeEvent != null)
375376
updateTextView(outcomeEvent.toString());
376377
}
@@ -380,7 +381,7 @@ public void onSuccess(@Nullable OutcomeEvent outcomeEvent) {
380381
public void onSendUniqueOutcomeClicked(View view) {
381382
OneSignal.sendUniqueOutcome(outcomeUnique.getText().toString(), new OneSignal.OutcomeCallback() {
382383
@Override
383-
public void onSuccess(@Nullable OutcomeEvent outcomeEvent) {
384+
public void onSuccess(@Nullable OSOutcomeEventParams outcomeEvent) {
384385
if (outcomeEvent != null)
385386
updateTextView(outcomeEvent.toString());
386387
}
@@ -393,7 +394,7 @@ public void onSendOutcomeWithValueClicked(View view) {
393394

394395
OneSignal.sendOutcomeWithValue(outcomeValueName.getText().toString(), Float.parseFloat(outcomeValue.getText().toString()), new OneSignal.OutcomeCallback() {
395396
@Override
396-
public void onSuccess(@Nullable OutcomeEvent outcomeEvent) {
397+
public void onSuccess(@Nullable OSOutcomeEventParams outcomeEvent) {
397398
if (outcomeEvent != null)
398399
updateTextView(outcomeEvent.toString());
399400
}

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

Lines changed: 0 additions & 21 deletions
This file was deleted.

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

Lines changed: 76 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,16 @@
55
import android.support.annotation.Nullable;
66
import android.support.annotation.WorkerThread;
77

8+
import com.onesignal.influence.model.OSInfluence;
9+
810
import org.json.JSONException;
911
import org.json.JSONObject;
1012

13+
import java.util.ArrayList;
1114
import java.util.Arrays;
15+
import java.util.HashSet;
1216
import java.util.List;
17+
import java.util.Set;
1318
import java.util.concurrent.atomic.AtomicBoolean;
1419

1520
/**
@@ -18,6 +23,7 @@
1823
* 2. App is foregrounded (appForegrounded) - Set start focused time
1924
* 3. App is backgrounded (appBackgrounded) - Kick off job to sync when session ends
2025
*/
26+
2127
class FocusTimeController {
2228
// Only present if app is currently in focus.
2329
@Nullable private Long timeFocusedAtMs;
@@ -44,13 +50,13 @@ void appForegrounded() {
4450
}
4551

4652
void appBackgrounded() {
47-
giveProcessorsValidFocusTime(OneSignal.getSessionManager().getSessionResult(), FocusEventType.BACKGROUND);
53+
giveProcessorsValidFocusTime(OneSignal.getSessionManager().getInfluences(), FocusEventType.BACKGROUND);
4854
timeFocusedAtMs = null;
4955
}
5056

51-
void onSessionEnded(@NonNull OSSessionManager.SessionResult lastSessionResult) {
57+
void onSessionEnded(@NonNull List<OSInfluence> lastInfluences) {
5258
final FocusEventType focusEventType = FocusEventType.END_SESSION;
53-
boolean hadValidTime = giveProcessorsValidFocusTime(lastSessionResult, focusEventType);
59+
boolean hadValidTime = giveProcessorsValidFocusTime(lastInfluences, focusEventType);
5460

5561
// If there is no in focus time to be added we just need to send the time from the last session that just ended.
5662
if (!hadValidTime) {
@@ -67,13 +73,13 @@ void doBlockingBackgroundSyncOfUnsentTime() {
6773
focusTimeProcessor.syncUnsentTimeFromSyncJob();
6874
}
6975

70-
private boolean giveProcessorsValidFocusTime(@NonNull OSSessionManager.SessionResult lastSessionResult, @NonNull FocusEventType focusType) {
76+
private boolean giveProcessorsValidFocusTime(@NonNull List<OSInfluence> influences, @NonNull FocusEventType focusType) {
7177
Long timeElapsed = getTimeFocusedElapsed();
7278
if (timeElapsed == null)
7379
return false;
7480

7581
for (FocusTimeProcessorBase focusTimeProcessor : focusTimeProcessors)
76-
focusTimeProcessor.addTime(timeElapsed, lastSessionResult.session, focusType);
82+
focusTimeProcessor.addTime(timeElapsed, influences, focusType);
7783
return true;
7884
}
7985

@@ -98,8 +104,14 @@ private static class FocusTimeProcessorUnattributed extends FocusTimeProcessorBa
98104
PREF_KEY_FOR_UNSENT_TIME = OneSignalPrefs.PREFS_GT_UNSENT_ACTIVE_TIME;
99105
}
100106

101-
protected boolean timeTypeApplies(@NonNull OSSessionManager.Session session) {
102-
return session.isUnattributed() || session.isDisabled();
107+
protected boolean timeTypeApplies(@NonNull List<OSInfluence> influences) {
108+
for (OSInfluence influence : influences) {
109+
// If at least one channel attributed the session then it is an attributed session.
110+
if (influence.getInfluenceType().isAttributed())
111+
return false;
112+
}
113+
OneSignal.Log(OneSignal.LOG_LEVEL.DEBUG, this.getClass().getSimpleName() + ":timeTypeApplies for influences: " + influences.toString() + " true");
114+
return true;
103115
}
104116

105117
protected void sendTime(@NonNull FocusEventType focusType) {
@@ -109,6 +121,11 @@ protected void sendTime(@NonNull FocusEventType focusType) {
109121

110122
syncUnsentTimeOnBackgroundEvent();
111123
}
124+
125+
@Override
126+
protected void saveInfluences(List<OSInfluence> influences) {
127+
// We don't save influences for unattributed
128+
}
112129
}
113130

114131
private static class FocusTimeProcessorAttributed extends FocusTimeProcessorBase {
@@ -117,12 +134,53 @@ private static class FocusTimeProcessorAttributed extends FocusTimeProcessorBase
117134
PREF_KEY_FOR_UNSENT_TIME = OneSignalPrefs.PREFS_OS_UNSENT_ATTRIBUTED_ACTIVE_TIME;
118135
}
119136

120-
protected boolean timeTypeApplies(@NonNull OSSessionManager.Session session) {
121-
return session.isAttributed();
137+
private List<OSInfluence> getInfluences() {
138+
List<OSInfluence> influences = new ArrayList<>();
139+
Set<String> influenceJSONs = OneSignalPrefs.getStringSet(
140+
OneSignalPrefs.PREFS_ONESIGNAL,
141+
OneSignalPrefs.PREFS_OS_ATTRIBUTED_INFLUENCES,
142+
new HashSet<String>()
143+
);
144+
145+
for (String influenceJSON : influenceJSONs) {
146+
try {
147+
influences.add(new OSInfluence(influenceJSON));
148+
} catch (JSONException exception) {
149+
OneSignal.Log(OneSignal.LOG_LEVEL.ERROR, this.getClass().getSimpleName() + ": error generation OSInfluence from json object: " + exception);
150+
}
151+
}
152+
return influences;
153+
}
154+
155+
@Override
156+
protected void saveInfluences(List<OSInfluence> influences) {
157+
Set<String> setInfluences = new HashSet<>();
158+
for (OSInfluence influence : influences) {
159+
try {
160+
setInfluences.add(influence.toJSONString());
161+
} catch (JSONException exception) {
162+
OneSignal.Log(OneSignal.LOG_LEVEL.ERROR, this.getClass().getSimpleName() + ": error generation json object OSInfluence: " + exception);
163+
}
164+
}
165+
166+
OneSignalPrefs.saveStringSet(
167+
OneSignalPrefs.PREFS_ONESIGNAL,
168+
OneSignalPrefs.PREFS_OS_ATTRIBUTED_INFLUENCES,
169+
setInfluences
170+
);
171+
}
172+
173+
protected boolean timeTypeApplies(@NonNull List<OSInfluence> influences) {
174+
for (OSInfluence influence : influences) {
175+
// Is true is at least one channel attributed the session
176+
if (influence.getInfluenceType().isAttributed())
177+
return true;
178+
}
179+
return false;
122180
}
123181

124182
protected void additionalFieldsToAddToOnFocusPayload(@NonNull JSONObject jsonBody) {
125-
OneSignal.getSessionManager().addSessionNotificationsIds(jsonBody);
183+
OneSignal.getSessionManager().addSessionIds(jsonBody, getInfluences());
126184
}
127185

128186
protected void sendTime(@NonNull FocusEventType focusType) {
@@ -134,12 +192,14 @@ protected void sendTime(@NonNull FocusEventType focusType) {
134192
}
135193

136194
private static abstract class FocusTimeProcessorBase {
195+
137196
// These values are set by child classes that inherit this base class
138197
protected long MIN_ON_FOCUS_TIME_SEC;
139198
protected @NonNull String PREF_KEY_FOR_UNSENT_TIME;
140199

141-
protected abstract boolean timeTypeApplies(@NonNull OSSessionManager.Session session);
200+
protected abstract boolean timeTypeApplies(@NonNull List<OSInfluence> influences);
142201
protected abstract void sendTime(@NonNull FocusEventType focusType);
202+
protected abstract void saveInfluences(List<OSInfluence> influences);
143203

144204
@Nullable private Long unsentActiveTime = null;
145205

@@ -165,10 +225,12 @@ private void saveUnsentActiveTime(long time) {
165225
);
166226
}
167227

168-
private void addTime(long time, @NonNull OSSessionManager.Session session, @NonNull FocusEventType focusType) {
169-
if (!timeTypeApplies(session))
228+
private void addTime(long time, @NonNull List<OSInfluence> influences, @NonNull FocusEventType focusType) {
229+
if (!timeTypeApplies(influences))
170230
return;
171231

232+
saveInfluences(influences);
233+
OneSignal.Log(OneSignal.LOG_LEVEL.DEBUG, this.getClass().getSimpleName() + ":addTime with lastFocusTimeInfluences: " + influences.toString());
172234
long totalTime = getUnsentActiveTime() + time;
173235
saveUnsentActiveTime(totalTime);
174236
sendUnsentTimeNow(focusType);
@@ -247,6 +309,7 @@ protected void additionalFieldsToAddToOnFocusPayload(@NonNull JSONObject jsonBod
247309

248310
private void sendOnFocus(long totalTimeActive) {
249311
try {
312+
OneSignal.Log(OneSignal.LOG_LEVEL.DEBUG, this.getClass().getSimpleName() + ":sendOnFocus with totalTimeActive: " + totalTimeActive);
250313
JSONObject jsonBody = generateOnFocusPayload(totalTimeActive);
251314
additionalFieldsToAddToOnFocusPayload(jsonBody);
252315
sendOnFocusToPlayer(OneSignal.getUserId(), jsonBody);

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ static void processNotification(NotificationGenerationJob notifiJob, boolean ope
162162
if (!notifiJob.isNotificationToDisplay())
163163
return;
164164
String notificationId = notifiJob.getApiNotificationId();
165-
OutcomesUtils.markLastNotificationReceived(notificationId);
165+
OneSignal.getSessionManager().onNotificationReceived(notificationId);
166166
OSReceiveReceiptController.getInstance().sendReceiveReceipt(notificationId);
167167
}
168168

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

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

3131
import android.content.Context;
3232
import android.net.Uri;
33+
import android.support.annotation.Nullable;
3334

3435
import org.json.JSONObject;
3536

@@ -93,6 +94,7 @@ boolean isNotificationToDisplay() {
9394
return getAndroidIdWithoutCreate() != -1;
9495
}
9596

97+
@Nullable
9698
String getApiNotificationId() {
9799
return OSNotificationFormatHelper.getOSNotificationIdFromJson(jsonPayload);
98100
}

0 commit comments

Comments
 (0)