Skip to content

Commit

Permalink
Showing 40 changed files with 351 additions and 52 deletions.
4 changes: 2 additions & 2 deletions Adjust/build.gradle
Original file line number Diff line number Diff line change
@@ -9,7 +9,7 @@ ext {
coreMinSdkVersion = 9
coreCompileSdkVersion = 28
coreTargetSdkVersion = 28
coreVersionName = '4.18.4' //append -SNAPSHOT for snapshot version
coreVersionName = '4.19.0' //append -SNAPSHOT for snapshot version
defaultVersionCode = 1

// POM.
@@ -24,7 +24,7 @@ buildscript {
google()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.5.1'
classpath 'com.android.tools.build:gradle:3.5.2'

// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files.
2 changes: 1 addition & 1 deletion Adjust/example-app-java/build.gradle
Original file line number Diff line number Diff line change
@@ -33,7 +33,7 @@ dependencies {
// implementation project(':plugin-imei')
// implementation project(":plugin-play")
// Add SDK via Maven.
// implementation 'com.adjust.sdk:adjust-android:4.18.4'
// implementation 'com.adjust.sdk:adjust-android:4.19.0'

debugImplementation 'com.squareup.leakcanary:leakcanary-android:1.6.2'
releaseImplementation 'com.squareup.leakcanary:leakcanary-android-no-op:1.6.2'
57 changes: 54 additions & 3 deletions Adjust/sdk-core/src/main/java/com/adjust/sdk/ActivityHandler.java
Original file line number Diff line number Diff line change
@@ -62,6 +62,7 @@ public class ActivityHandler implements IActivityHandler {
private InternalState internalState;
private String basePath;
private String gdprPath;
private String disableThirdPartySharingPath;

private DeviceInfo deviceInfo;
private AdjustConfig adjustConfig; // always valid after construction
@@ -608,6 +609,16 @@ public void run() {
});
}

@Override
public void disableThirdPartySharing() {
executor.submit(new Runnable() {
@Override
public void run() {
disableThirdPartySharingI();
}
});
}

@Override
public void trackAdRevenue(final String source, final JSONObject adRevenueJson) {
executor.submit(new Runnable() {
@@ -765,6 +776,8 @@ public void run(ActivityHandler activityHandler) {
SharedPreferencesManager sharedPreferencesManager = new SharedPreferencesManager(getContext());
if (sharedPreferencesManager.getGdprForgetMe()) {
gdprForgetMe();
} else if (sharedPreferencesManager.getDisableThirdPartySharing()) {
disableThirdPartySharing();
}
}

@@ -895,12 +908,17 @@ private void startFirstSessionI() {

// track the first session package only if it's enabled
if (internalState.isEnabled()) {
if (!sharedPreferencesManager.getGdprForgetMe()) {
if (sharedPreferencesManager.getGdprForgetMe()) {
gdprForgetMeI();
} else {
// check if disable third party sharing request came, then send it first
if (sharedPreferencesManager.getDisableThirdPartySharing()) {
disableThirdPartySharingI();
}

activityState.sessionCount = 1; // this is the first session
transferSessionPackageI(now);
checkAfterNewStartI(sharedPreferencesManager);
} else {
gdprForgetMeI();
}
}

@@ -911,6 +929,7 @@ private void startFirstSessionI() {
writeActivityStateI();
sharedPreferencesManager.removePushToken();
sharedPreferencesManager.removeGdprForgetMe();
sharedPreferencesManager.removeDisableThirdPartySharing();

// check for cached deep links
processCachedDeeplinkI();
@@ -1322,6 +1341,8 @@ private void setEnabledI(boolean enabled) {

if (sharedPreferencesManager.getGdprForgetMe()) {
gdprForgetMeI();
} else if (sharedPreferencesManager.getDisableThirdPartySharing()) {
disableThirdPartySharingI();
}

// check if install was tracked
@@ -1879,6 +1900,36 @@ private void gdprForgetMeI() {
}
}

private void disableThirdPartySharingI() {
// cache the disable third party sharing request, so that the request order maintains
// even this call returns before making server request
SharedPreferencesManager sharedPreferencesManager = new SharedPreferencesManager(getContext());
sharedPreferencesManager.setDisableThirdPartySharing();

if (!checkActivityStateI(activityState)) { return; }
if (!isEnabledI()) { return; }
if (activityState.isGdprForgotten) { return; }
if (activityState.isThirdPartySharingDisabled) { return; }

activityState.isThirdPartySharingDisabled = true;
writeActivityStateI();

long now = System.currentTimeMillis();
PackageBuilder packageBuilder = new PackageBuilder(adjustConfig, deviceInfo, activityState, sessionParameters, now);

ActivityPackage activityPackage = packageBuilder.buildDisableThirdPartySharingPackage();
packageHandler.addPackage(activityPackage);

// Removed the cached disable third party sharing flag.
sharedPreferencesManager.removeDisableThirdPartySharing();

if (adjustConfig.eventBufferingEnabled) {
logger.info("Buffered event %s", activityPackage.getSuffix());
} else {
packageHandler.sendFirstPackage();
}
}

private void trackAdRevenueI(String source, JSONObject adRevenueJson) {
if (!checkActivityStateI(activityState)) { return; }
if (!isEnabledI()) { return; }
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.adjust.sdk;

public enum ActivityKind {
UNKNOWN, SESSION, EVENT, CLICK, ATTRIBUTION, REVENUE, REATTRIBUTION, INFO, GDPR, AD_REVENUE;
UNKNOWN, SESSION, EVENT, CLICK, ATTRIBUTION, REVENUE, REATTRIBUTION, INFO, GDPR, AD_REVENUE, DISABLE_THIRD_PARTY_SHARING;

public static ActivityKind fromString(String string) {
if ("session".equals(string)) {
@@ -16,6 +16,8 @@ public static ActivityKind fromString(String string) {
return INFO;
} else if ("gdpr".equals(string)) {
return GDPR;
} else if ("disable_third_party_sharing".equals(string)) {
return DISABLE_THIRD_PARTY_SHARING;
} else if ("ad_revenue".equals(string)) {
return AD_REVENUE;
} else {
@@ -38,6 +40,8 @@ public String toString() {
return "info";
case GDPR:
return "gdpr";
case DISABLE_THIRD_PARTY_SHARING:
return "disable_third_party_sharing";
case AD_REVENUE:
return "ad_revenue";
default:
Original file line number Diff line number Diff line change
@@ -17,7 +17,6 @@
import java.io.Serializable;
import java.util.Calendar;
import java.util.LinkedList;
import java.util.Locale;

public class ActivityState implements Serializable, Cloneable {
private static final long serialVersionUID = 9039439291143138148L;
@@ -27,6 +26,7 @@ public class ActivityState implements Serializable, Cloneable {
new ObjectStreamField("uuid", String.class),
new ObjectStreamField("enabled", boolean.class),
new ObjectStreamField("isGdprForgotten", boolean.class),
new ObjectStreamField("isThirdPartySharingDisabled", boolean.class),
new ObjectStreamField("askingAttribution", boolean.class),
new ObjectStreamField("eventCount", int.class),
new ObjectStreamField("sessionCount", int.class),
@@ -48,6 +48,7 @@ public class ActivityState implements Serializable, Cloneable {
protected String uuid;
protected boolean enabled;
protected boolean isGdprForgotten;
protected boolean isThirdPartySharingDisabled;
protected boolean askingAttribution;

// global counters
@@ -79,6 +80,7 @@ protected ActivityState() {
uuid = Util.createUuid();
enabled = true;
isGdprForgotten = false;
isThirdPartySharingDisabled = false;
askingAttribution = false;
eventCount = 0; // no events yet
sessionCount = 0; // the first session just started
@@ -140,6 +142,7 @@ public boolean equals(Object other) {
if (!Util.equalString(uuid, otherActivityState.uuid)) return false;
if (!Util.equalBoolean(enabled, otherActivityState.enabled)) return false;
if (!Util.equalBoolean(isGdprForgotten, otherActivityState.isGdprForgotten)) return false;
if (!Util.equalBoolean(isThirdPartySharingDisabled, otherActivityState.isThirdPartySharingDisabled)) return false;
if (!Util.equalBoolean(askingAttribution, otherActivityState.askingAttribution)) return false;
if (!Util.equalInt(eventCount, otherActivityState.eventCount)) return false;
if (!Util.equalInt(sessionCount, otherActivityState.sessionCount)) return false;
@@ -163,6 +166,7 @@ public int hashCode() {
hashCode = 37 * hashCode + Util.hashString(uuid);
hashCode = 37 * hashCode + Util.hashBoolean(enabled);
hashCode = 37 * hashCode + Util.hashBoolean(isGdprForgotten);
hashCode = 37 * hashCode + Util.hashBoolean(isThirdPartySharingDisabled);
hashCode = 37 * hashCode + Util.hashBoolean(askingAttribution);
hashCode = 37 * hashCode + eventCount;
hashCode = 37 * hashCode + sessionCount;
@@ -195,6 +199,7 @@ private void readObject(ObjectInputStream stream) throws IOException, ClassNotFo
uuid = Util.readStringField(fields, "uuid", null);
enabled = Util.readBooleanField(fields, "enabled", true);
isGdprForgotten = Util.readBooleanField(fields, "isGdprForgotten", false);
isThirdPartySharingDisabled = Util.readBooleanField(fields, "isThirdPartySharingDisabled", false);
askingAttribution = Util.readBooleanField(fields, "askingAttribution", false);

updatePackages = Util.readBooleanField(fields, "updatePackages", false);
12 changes: 11 additions & 1 deletion Adjust/sdk-core/src/main/java/com/adjust/sdk/Adjust.java
Original file line number Diff line number Diff line change
@@ -32,7 +32,7 @@ private Adjust() {
*/
public static synchronized AdjustInstance getDefaultInstance() {
@SuppressWarnings("unused")
String VERSION = "!SDK-VERSION-STRING!:com.adjust.sdk:adjust-android:4.18.4";
String VERSION = "!SDK-VERSION-STRING!:com.adjust.sdk:adjust-android:4.19.0";

if (defaultInstance == null) {
defaultInstance = new AdjustInstance();
@@ -239,6 +239,16 @@ public static void gdprForgetMe(final Context context) {
adjustInstance.gdprForgetMe(context);
}

/**
* Called to disable the third party sharing.
*
* @param context Application context
*/
public static void disableThirdPartySharing(final Context context) {
AdjustInstance adjustInstance = Adjust.getDefaultInstance();
adjustInstance.disableThirdPartySharing(context);
}

/**
* Track ad revenue from a source provider
*
30 changes: 30 additions & 0 deletions Adjust/sdk-core/src/main/java/com/adjust/sdk/AdjustInstance.java
Original file line number Diff line number Diff line change
@@ -389,6 +389,20 @@ public void gdprForgetMe(final Context context) {
}
}

/**
* Called to disable the third party sharing.
*
* @param context Application context
*/
public void disableThirdPartySharing(final Context context) {
if (!checkActivityHandler("disable third party sharing")) {
saveDisableThirdPartySharing(context);
return;
}

activityHandler.disableThirdPartySharing();
}

/**
* Track ad revenue from a source provider
*
@@ -532,6 +546,22 @@ public void run() {
Util.runInBackground(command);
}

/**
* Save disable third party sharing choice to shared preferences.
*
* @param context Application context
*/
private void saveDisableThirdPartySharing(final Context context) {
Runnable command = new Runnable() {
@Override
public void run() {
SharedPreferencesManager sharedPreferencesManager = new SharedPreferencesManager(context);
sharedPreferencesManager.setDisableThirdPartySharing();
}
};
Util.runInBackground(command);
}

/**
* Flag stored referrers as still not sent.
*
Original file line number Diff line number Diff line change
@@ -30,7 +30,7 @@ public interface Constants {
String GDPR_URL = "https://gdpr.adjust.com";
String SCHEME = "https";
String AUTHORITY = "app.adjust.com";
String CLIENT_SDK = "android4.18.4";
String CLIENT_SDK = "android4.19.0";
String LOGTAG = "Adjust";
String REFTAG = "reftag";
String INSTALL_REFERRER = "install_referrer";
Original file line number Diff line number Diff line change
@@ -63,6 +63,8 @@ public interface IActivityHandler {

void gdprForgetMe();

void disableThirdPartySharing();

void trackAdRevenue(String source, JSONObject adRevenueJson);

void gotOptOutResponse();
65 changes: 65 additions & 0 deletions Adjust/sdk-core/src/main/java/com/adjust/sdk/PackageBuilder.java
Original file line number Diff line number Diff line change
@@ -135,6 +135,15 @@ ActivityPackage buildGdprPackage() {
return gdprPackage;
}

ActivityPackage buildDisableThirdPartySharingPackage() {
Map<String, String> parameters = getDisableThirdPartySharingParameters();
ActivityPackage activityPackage = getDefaultActivityPackage(ActivityKind.DISABLE_THIRD_PARTY_SHARING);
activityPackage.setPath("/disable_third_party_sharing");
activityPackage.setSuffix("");
activityPackage.setParameters(parameters);
return activityPackage;
}

ActivityPackage buildAdRevenuePackage(String source, JSONObject adRevenueJson) {
Map<String, String> parameters = getAdRevenueParameters(source, adRevenueJson);
ActivityPackage adRevenuePackage = getDefaultActivityPackage(ActivityKind.AD_REVENUE);
@@ -579,6 +588,62 @@ private Map<String, String> getGdprParameters() {
return parameters;
}

private Map<String, String> getDisableThirdPartySharingParameters() {
ContentResolver contentResolver = adjustConfig.context.getContentResolver();
Map<String, String> parameters = new HashMap<String, String>();
Map<String, String> imeiParameters = Reflection.getImeiParameters(adjustConfig.context, logger);

// Check if plugin is used and if yes, add read parameters.
if (imeiParameters != null) {
parameters.putAll(imeiParameters);
}

// Check if oaid plugin is used and if yes, add the parameter
Map<String, String> oaidParameters = Reflection.getOaidParameters(adjustConfig.context, logger);
if (oaidParameters != null) {
parameters.putAll(oaidParameters);
}

// Device identifiers.
deviceInfo.reloadPlayIds(adjustConfig.context);
PackageBuilder.addString(parameters, "android_uuid", activityStateCopy.uuid);
PackageBuilder.addBoolean(parameters, "tracking_enabled", deviceInfo.isTrackingEnabled);
PackageBuilder.addString(parameters, "gps_adid", deviceInfo.playAdId);
PackageBuilder.addString(parameters, "gps_adid_src", deviceInfo.playAdIdSource);

if (!containsPlayIds(parameters)) {
logger.warn("Google Advertising ID not detected, fallback to non Google Play identifiers will take place");
deviceInfo.reloadNonPlayIds(adjustConfig.context);
PackageBuilder.addString(parameters, "mac_sha1", deviceInfo.macSha1);
PackageBuilder.addString(parameters, "mac_md5", deviceInfo.macShortMd5);
PackageBuilder.addString(parameters, "android_id", deviceInfo.androidId);
}

// Rest of the parameters.
PackageBuilder.addString(parameters, "api_level", deviceInfo.apiLevel);
PackageBuilder.addString(parameters, "app_secret", adjustConfig.appSecret);
PackageBuilder.addString(parameters, "app_token", adjustConfig.appToken);
PackageBuilder.addString(parameters, "app_version", deviceInfo.appVersion);
PackageBuilder.addBoolean(parameters, "attribution_deeplink", true);
PackageBuilder.addDateInMilliseconds(parameters, "created_at", createdAt);
PackageBuilder.addBoolean(parameters, "device_known", adjustConfig.deviceKnown);
PackageBuilder.addString(parameters, "device_name", deviceInfo.deviceName);
PackageBuilder.addString(parameters, "device_type", deviceInfo.deviceType);
PackageBuilder.addString(parameters, "environment", adjustConfig.environment);
PackageBuilder.addBoolean(parameters, "event_buffering_enabled", adjustConfig.eventBufferingEnabled);
PackageBuilder.addString(parameters, "fire_adid", Util.getFireAdvertisingId(contentResolver));
PackageBuilder.addBoolean(parameters, "fire_tracking_enabled", Util.getFireTrackingEnabled(contentResolver));
PackageBuilder.addBoolean(parameters, "needs_response_details", true);
PackageBuilder.addString(parameters, "os_name", deviceInfo.osName);
PackageBuilder.addString(parameters, "os_version", deviceInfo.osVersion);
PackageBuilder.addString(parameters, "package_name", deviceInfo.packageName);
PackageBuilder.addString(parameters, "push_token", activityStateCopy.pushToken);
PackageBuilder.addString(parameters, "secret_id", adjustConfig.secretId);

checkDeviceIds(parameters);
return parameters;
}

private Map<String, String> getAdRevenueParameters(String source, JSONObject adRevenueJson) {
ContentResolver contentResolver = adjustConfig.context.getContentResolver();
Map<String, String> parameters = new HashMap<String, String>();
Loading

0 comments on commit 9e4b256

Please sign in to comment.