Skip to content

Commit 2602ae6

Browse files
authored
Merge pull request #331 from adjust/v4130
Version 4.13.0
2 parents f199d24 + 51b8ea7 commit 2602ae6

39 files changed

+527
-92
lines changed

Adjust/adjust/adjust-proguard-rules.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@
1717
java.lang.String CPU_ABI;
1818
}
1919
-keep class android.content.res.Configuration {
20-
android.os.LocaledList getLocales();
20+
android.os.LocaleList getLocales();
2121
java.util.Locale locale;
2222
}
23-
-keep class android.os.LocaledList {
23+
-keep class android.os.LocaleList {
2424
java.util.Locale get(int);
2525
}
2626
-keep public class com.android.installreferrer.** { *; }

Adjust/adjust/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
apply plugin: 'com.android.library'
22

33
def getVersionName() {
4-
return "4.12.4"
4+
return "4.13.0"
55
}
66

77
android {

Adjust/adjust/src/main/java/com/adjust/sdk/ActivityHandler.java

Lines changed: 98 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ public class ActivityHandler implements IActivityHandler {
5454
private TimerOnce delayStartTimer;
5555
private InternalState internalState;
5656
private String basePath;
57+
private String gdprPath;
5758

5859
private DeviceInfo deviceInfo;
5960
private AdjustConfig adjustConfig; // always valid after construction
@@ -592,6 +593,26 @@ public void run() {
592593
});
593594
}
594595

596+
@Override
597+
public void gdprForgetMe() {
598+
scheduledExecutor.submit(new Runnable() {
599+
@Override
600+
public void run() {
601+
gdprForgetMeI();
602+
}
603+
});
604+
}
605+
606+
@Override
607+
public void gotOptOutResponse() {
608+
scheduledExecutor.submit(new Runnable() {
609+
@Override
610+
public void run() {
611+
gotOptOutResponseI();
612+
}
613+
});
614+
}
615+
595616
@Override
596617
public Context getContext() {
597618
return adjustConfig.context;
@@ -633,6 +654,11 @@ public String getBasePath() {
633654
return this.basePath;
634655
}
635656

657+
@Override
658+
public String getGdprPath() {
659+
return this.gdprPath;
660+
}
661+
636662
public ActivityPackage getAttributionPackageI() {
637663
long now = System.currentTimeMillis();
638664
PackageBuilder attributionBuilder = new PackageBuilder(adjustConfig,
@@ -727,6 +753,14 @@ public void run(ActivityHandler activityHandler) {
727753
}
728754
}
729755

756+
// GDPR
757+
if (internalState.hasFirstSdkStartOcurred()) {
758+
SharedPreferencesManager sharedPreferencesManager = new SharedPreferencesManager(getContext());
759+
if (sharedPreferencesManager.getGdprForgetMe()) {
760+
gdprForgetMe();
761+
}
762+
}
763+
730764
foregroundTimer = new TimerCycle(
731765
new Runnable() {
732766
@Override
@@ -765,6 +799,7 @@ public void run() {
765799
UtilNetworking.setUserAgent(adjustConfig.userAgent);
766800

767801
this.basePath = adjustConfig.basePath;
802+
this.gdprPath = adjustConfig.gdprPath;
768803

769804
packageHandler = AdjustFactory.getPackageHandler(this, adjustConfig.context, toSendI(false));
770805

@@ -780,10 +815,8 @@ public void run() {
780815
updatePackagesI();
781816
}
782817

783-
preLaunchActionsI(adjustConfig.preLaunchActionsArray);
784-
785818
installReferrer = new InstallReferrer(adjustConfig.context, this);
786-
819+
preLaunchActionsI(adjustConfig.preLaunchActionsArray);
787820
sendReftagReferrerI();
788821
}
789822

@@ -848,13 +881,17 @@ private void startFirstSessionI() {
848881

849882
SharedPreferencesManager sharedPreferencesManager = new SharedPreferencesManager(getContext());
850883
activityState.pushToken = sharedPreferencesManager.getPushToken();
884+
// activityState.isGdprForgotten = sharedPreferencesManager.getGdprForgetMe();
851885

852886
// track the first session package only if it's enabled
853887
if (internalState.isEnabled()) {
854-
activityState.sessionCount = 1; // this is the first session
855-
transferSessionPackageI(now);
856-
857-
checkAfterNewStartI(sharedPreferencesManager);
888+
if (!sharedPreferencesManager.getGdprForgetMe()) {
889+
activityState.sessionCount = 1; // this is the first session
890+
transferSessionPackageI(now);
891+
checkAfterNewStartI(sharedPreferencesManager);
892+
} else {
893+
gdprForgetMeI();
894+
}
858895
}
859896

860897
activityState.resetSessionAttributes(now);
@@ -863,11 +900,16 @@ private void startFirstSessionI() {
863900

864901
writeActivityStateI();
865902
sharedPreferencesManager.removePushToken();
903+
sharedPreferencesManager.removeGdprForgetMe();
866904

867905
// don't check attribution right after first sdk start
868906
}
869907

870908
private void processSessionI() {
909+
if (activityState.isGdprForgotten) {
910+
return;
911+
}
912+
871913
long now = System.currentTimeMillis();
872914

873915
long lastInterval = now - activityState.lastActivity;
@@ -951,6 +993,7 @@ private void trackEventI(AdjustEvent event) {
951993
if (!isEnabledI()) return;
952994
if (!checkEventI(event)) return;
953995
if (!checkOrderIdI(event.orderId)) return;
996+
if (activityState.isGdprForgotten) return;
954997

955998
long now = System.currentTimeMillis();
956999

@@ -1213,6 +1256,13 @@ private void setEnabledI(boolean enabled) {
12131256
return;
12141257
}
12151258

1259+
if (enabled) {
1260+
if (activityState.isGdprForgotten) {
1261+
logger.error("Re-enabling SDK not possible for forgotten user");
1262+
return;
1263+
}
1264+
}
1265+
12161266
// save new enabled state in internal state
12171267
internalState.enabled = enabled;
12181268

@@ -1224,9 +1274,16 @@ private void setEnabledI(boolean enabled) {
12241274
return;
12251275
}
12261276

1277+
activityState.enabled = enabled;
1278+
writeActivityStateI();
1279+
12271280
if (enabled) {
12281281
SharedPreferencesManager sharedPreferencesManager = new SharedPreferencesManager(getContext());
12291282

1283+
if (sharedPreferencesManager.getGdprForgetMe()) {
1284+
gdprForgetMeI();
1285+
}
1286+
12301287
// check if install was tracked
12311288
if (!sharedPreferencesManager.getInstallTracked()) {
12321289
long now = System.currentTimeMillis();
@@ -1235,9 +1292,6 @@ private void setEnabledI(boolean enabled) {
12351292
checkAfterNewStartI(sharedPreferencesManager);
12361293
}
12371294

1238-
activityState.enabled = enabled;
1239-
writeActivityStateI();
1240-
12411295
updateStatusI(!enabled,
12421296
"Pausing handlers due to SDK being disabled",
12431297
"Handlers remain paused",
@@ -1729,6 +1783,7 @@ public void resetSessionPartnerParametersI() {
17291783
private void setPushTokenI(String token) {
17301784
if (!checkActivityStateI(activityState)) { return; }
17311785
if (!isEnabledI()) { return; }
1786+
if (activityState.isGdprForgotten) { return; }
17321787

17331788
if (token == null) { return; }
17341789
if (token.equals(activityState.pushToken)) { return; }
@@ -1754,6 +1809,39 @@ private void setPushTokenI(String token) {
17541809
}
17551810
}
17561811

1812+
private void gdprForgetMeI() {
1813+
if (!checkActivityStateI(activityState)) { return; }
1814+
if (!isEnabledI()) { return; }
1815+
if (activityState.isGdprForgotten) { return; }
1816+
1817+
activityState.isGdprForgotten = true;
1818+
writeActivityStateI();
1819+
1820+
long now = System.currentTimeMillis();
1821+
PackageBuilder gdprPackageBuilder = new PackageBuilder(adjustConfig, deviceInfo, activityState, sessionParameters, now);
1822+
1823+
ActivityPackage gdprPackage = gdprPackageBuilder.buildGdprPackage();
1824+
packageHandler.addPackage(gdprPackage);
1825+
1826+
// If GDPR choice was cached, remove it.
1827+
SharedPreferencesManager sharedPreferencesManager = new SharedPreferencesManager(getContext());
1828+
sharedPreferencesManager.removeGdprForgetMe();
1829+
1830+
if (adjustConfig.eventBufferingEnabled) {
1831+
logger.info("Buffered event %s", gdprPackage.getSuffix());
1832+
} else {
1833+
packageHandler.sendFirstPackage();
1834+
}
1835+
}
1836+
1837+
private void gotOptOutResponseI() {
1838+
activityState.isGdprForgotten = true;
1839+
writeActivityStateI();
1840+
1841+
packageHandler.flush();
1842+
setEnabledI(false);
1843+
}
1844+
17571845
private void readActivityStateI(Context context) {
17581846
try {
17591847
activityState = Util.readObject(context, ACTIVITY_STATE_FILENAME, ACTIVITY_STATE_NAME, ActivityState.class);

Adjust/adjust/src/main/java/com/adjust/sdk/ActivityKind.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package com.adjust.sdk;
22

33
public enum ActivityKind {
4-
UNKNOWN, SESSION, EVENT, CLICK, ATTRIBUTION, REVENUE, REATTRIBUTION, INFO;
4+
UNKNOWN, SESSION, EVENT, CLICK, ATTRIBUTION, REVENUE, REATTRIBUTION, INFO, GDPR;
55

66
public static ActivityKind fromString(String string) {
77
if ("session".equals(string)) {
@@ -14,6 +14,8 @@ public static ActivityKind fromString(String string) {
1414
return ATTRIBUTION;
1515
} else if ("info".equals(string)) {
1616
return INFO;
17+
} else if ("gdpr".equals(string)) {
18+
return GDPR;
1719
} else {
1820
return UNKNOWN;
1921
}
@@ -32,6 +34,8 @@ public String toString() {
3234
return "attribution";
3335
case INFO:
3436
return "info";
37+
case GDPR:
38+
return "gdpr";
3539
default:
3640
return "unknown";
3741
}

Adjust/adjust/src/main/java/com/adjust/sdk/ActivityState.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ public class ActivityState implements Serializable, Cloneable {
2626
private static final ObjectStreamField[] serialPersistentFields = {
2727
new ObjectStreamField("uuid", String.class),
2828
new ObjectStreamField("enabled", boolean.class),
29+
new ObjectStreamField("isGdprForgotten", boolean.class),
2930
new ObjectStreamField("askingAttribution", boolean.class),
3031
new ObjectStreamField("eventCount", int.class),
3132
new ObjectStreamField("sessionCount", int.class),
@@ -46,6 +47,7 @@ public class ActivityState implements Serializable, Cloneable {
4647
// persistent data
4748
protected String uuid;
4849
protected boolean enabled;
50+
protected boolean isGdprForgotten;
4951
protected boolean askingAttribution;
5052

5153
// global counters
@@ -76,6 +78,7 @@ protected ActivityState() {
7678
// create UUID for new devices
7779
uuid = Util.createUuid();
7880
enabled = true;
81+
isGdprForgotten = false;
7982
askingAttribution = false;
8083
eventCount = 0; // no events yet
8184
sessionCount = 0; // the first session just started
@@ -136,6 +139,7 @@ public boolean equals(Object other) {
136139

137140
if (!Util.equalString(uuid, otherActivityState.uuid)) return false;
138141
if (!Util.equalBoolean(enabled, otherActivityState.enabled)) return false;
142+
if (!Util.equalBoolean(isGdprForgotten, otherActivityState.isGdprForgotten)) return false;
139143
if (!Util.equalBoolean(askingAttribution, otherActivityState.askingAttribution)) return false;
140144
if (!Util.equalInt(eventCount, otherActivityState.eventCount)) return false;
141145
if (!Util.equalInt(sessionCount, otherActivityState.sessionCount)) return false;
@@ -158,6 +162,7 @@ public int hashCode() {
158162
int hashCode = 17;
159163
hashCode = 37 * hashCode + Util.hashString(uuid);
160164
hashCode = 37 * hashCode + Util.hashBoolean(enabled);
165+
hashCode = 37 * hashCode + Util.hashBoolean(isGdprForgotten);
161166
hashCode = 37 * hashCode + Util.hashBoolean(askingAttribution);
162167
hashCode = 37 * hashCode + eventCount;
163168
hashCode = 37 * hashCode + sessionCount;
@@ -189,6 +194,7 @@ private void readObject(ObjectInputStream stream) throws IOException, ClassNotFo
189194
// new fields
190195
uuid = Util.readStringField(fields, "uuid", null);
191196
enabled = Util.readBooleanField(fields, "enabled", true);
197+
isGdprForgotten = Util.readBooleanField(fields, "isGdprForgotten", false);
192198
askingAttribution = Util.readBooleanField(fields, "askingAttribution", false);
193199

194200
updatePackages = Util.readBooleanField(fields, "updatePackages", false);

0 commit comments

Comments
 (0)