Skip to content

Commit

Permalink
feat: Android id disabled default true (mParticle#89)
Browse files Browse the repository at this point in the history
* feat: Change default value for isAndroidIdDisabled() to true

* feat: Deprecate isAndroidDisabled(), add isAndroidEnabled()
  • Loading branch information
willpassidomo authored Jan 12, 2022
1 parent 29b38fc commit 7fc0217
Show file tree
Hide file tree
Showing 6 changed files with 179 additions and 39 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
import org.junit.Rule;
import org.junit.Test;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.CountDownLatch;

Expand Down Expand Up @@ -152,13 +154,48 @@ public void testSetCredentials() throws Exception {

@Test
public void testAndroidIdDisabled() throws Exception {
//test defaults
assertFalse(MParticle.isAndroidIdEnabled());
assertTrue(MParticle.isAndroidIdDisabled());
MParticle.setInstance(null);
startMParticle(MParticleOptions.builder(mContext)
.androidIdDisabled(true));
startMParticle(MParticleOptions.builder(mContext));
assertFalse(MParticle.isAndroidIdEnabled());
assertTrue(MParticle.isAndroidIdDisabled());

//test androidIdDisabled == true
MParticle.setInstance(null);
startMParticle(MParticleOptions.builder(mContext)
.androidIdDisabled(false));
startMParticle(
MParticleOptions.builder(mContext)
.androidIdDisabled(true)
);
assertFalse(MParticle.isAndroidIdEnabled());
assertTrue(MParticle.isAndroidIdDisabled());
MParticle.setInstance(null);

//test androidIdEnabled == false
MParticle.setInstance(null);
startMParticle(
MParticleOptions.builder(mContext)
.androidIdEnabled(false)
);
assertFalse(MParticle.isAndroidIdEnabled());
assertTrue(MParticle.isAndroidIdDisabled());
MParticle.setInstance(null);

//test androidIdDisabled == false
startMParticle(
MParticleOptions.builder(mContext)
.androidIdDisabled(false)
);
assertTrue(MParticle.isAndroidIdEnabled());
assertFalse(MParticle.isAndroidIdDisabled());

//test androidIdEnabled == true
startMParticle(
MParticleOptions.builder(mContext)
.androidIdEnabled(true)
);
assertTrue(MParticle.isAndroidIdEnabled());
assertFalse(MParticle.isAndroidIdDisabled());
}

Expand Down Expand Up @@ -456,4 +493,38 @@ public void testConfigStaleness() {
assertNull(options.getConfigMaxAge());
}

@Test
public void testAndroidIdLogMessage() {
List<String> infoLogs = new ArrayList();
Logger.setLogHandler(new Logger.DefaultLogHandler() {
@Override
public void log(MParticle.LogLevel priority, Throwable error, String messages) {
super.log(priority, error, messages);
if (priority == MParticle.LogLevel.INFO) {
infoLogs.add(messages);
}
}
});
MParticleOptions.builder(mContext)
.credentials("this", "that")
.androidIdDisabled(true)
.build();
assertTrue(infoLogs.contains("ANDROID_ID will not be collected based on MParticleOptions settings"));
infoLogs.clear();

MParticleOptions.builder(mContext)
.credentials("this", "that")
.androidIdDisabled(false)
.build();
assertTrue(infoLogs.contains("ANDROID_ID will be collected based on MParticleOptions settings"));
infoLogs.clear();

//test default
MParticleOptions.builder(mContext)
.credentials("this", "that")
.build();

assertTrue(infoLogs.contains("ANDROID_ID will not be collected based on default settings"));
infoLogs.clear();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,11 @@ public void testInitialIdentitiesPresentWithAndroidId() throws Exception {
.userIdentities(identities)
.build();
startMParticle(MParticleOptions.builder(mContext)
.androidIdDisabled(false)
.androidIdEnabled(true)
.identify(request));

assertTrue(mServer.Requests().getIdentify().size() == 1);
assertIdentitiesMatch(mServer.Requests().getIdentify().get(0), identities, false);
assertIdentitiesMatch(mServer.Requests().getIdentify().get(0), identities, true);
}

@Test
Expand All @@ -55,11 +55,11 @@ public void testInitialIdentitiesPresentWithoutAndroidId() throws Exception {
.userIdentities(identities)
.build();
startMParticle(MParticleOptions.builder(mContext)
.androidIdDisabled(true)
.androidIdEnabled(false)
.identify(request));

assertTrue(mServer.Requests().getIdentify().size() == 1);
assertIdentitiesMatch(mServer.Requests().getIdentify().get(0), identities, true);
assertIdentitiesMatch(mServer.Requests().getIdentify().get(0), identities, false);
}


Expand Down Expand Up @@ -175,18 +175,18 @@ public boolean isMatch(JSONObject jsonObject) {
assertTrue(called.value);
}

private void assertIdentitiesMatch(Request request, Map<MParticle.IdentityType, String> identities, boolean androidIdDisabled) throws Exception {
private void assertIdentitiesMatch(Request request, Map<MParticle.IdentityType, String> identities, boolean androidIdEnabled) throws Exception {
assertTrue(request instanceof IdentityRequest);
IdentityRequest identityRequest = request.asIdentityRequest();
assertNotNull(identityRequest);

JSONObject knownIdentities = identityRequest.getBody().known_identities;
assertNotNull(knownIdentities);

if (androidIdDisabled) {
assertFalse(knownIdentities.has("android_uuid"));
} else {
if (androidIdEnabled) {
assertNotNull(knownIdentities.remove("android_uuid"));
} else {
assertFalse(knownIdentities.has("android_uuid"));
}
assertNotNull(knownIdentities.remove("device_application_stamp"));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,27 +11,44 @@
import org.junit.Test;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;

public class DeviceAttributesTests extends BaseCleanInstallEachTest {

@Test
public void testAndroidIDCollection() throws Exception {
Context context = InstrumentationRegistry.getInstrumentation().getContext();
String androidId = MPUtility.getAndroidID(context);
JSONObject attributes = new JSONObject();
DeviceAttributes.addAndroidId(attributes, context);
assertEquals(attributes.getString(Constants.MessageKey.DEVICE_ANID),androidId);
assertTrue(attributes.getString(Constants.MessageKey.DEVICE_OPEN_UDID).length() > 0);
assertEquals(attributes.getString(Constants.MessageKey.DEVICE_ID),androidId);
assertFalse(attributes.has(Constants.MessageKey.DEVICE_ANID));
assertFalse(attributes.has(Constants.MessageKey.DEVICE_OPEN_UDID));
assertFalse(attributes.has(Constants.MessageKey.DEVICE_ID));

MParticleOptions options = MParticleOptions.builder(context)
.androidIdDisabled(true)
.androidIdEnabled(false)
.credentials("key", "secret")
.build();
MParticle.start(options);
JSONObject newAttributes = new JSONObject();
DeviceAttributes.addAndroidId(attributes, context);
DeviceAttributes.addAndroidId(newAttributes, context);
assertTrue(newAttributes.length() == 0);

MParticle.setInstance(null);

options = MParticleOptions.builder(context)
.androidIdEnabled(true)
.credentials("key", "secret")
.build();
MParticle.start(options);
newAttributes = new JSONObject();
String androidId = MPUtility.getAndroidID(context);
DeviceAttributes.addAndroidId(newAttributes, context);
assertTrue(newAttributes.length() == 3);
assertEquals(newAttributes.getString(Constants.MessageKey.DEVICE_ANID),androidId);
assertTrue(newAttributes.getString(Constants.MessageKey.DEVICE_OPEN_UDID).length() > 0);
assertEquals(newAttributes.getString(Constants.MessageKey.DEVICE_ID),androidId);

}
}
36 changes: 27 additions & 9 deletions android-core/src/main/java/com/mparticle/MParticle.java
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ public class MParticle {
@NonNull protected MParticleDBManager mDatabaseManager;
@NonNull protected volatile AttributionListener mAttributionListener;
@NonNull protected IdentityApi mIdentityApi;
static volatile boolean sAndroidIdDisabled;
static volatile boolean sAndroidIdEnabled = false;
static volatile boolean sDevicePerformanceMetricsDisabled;
@NonNull protected boolean locationTrackingEnabled = false;
@NonNull protected Internal mInternal = new Internal();
Expand Down Expand Up @@ -143,7 +143,7 @@ private static MParticle getInstance(@NonNull Context context, @NonNull MParticl
synchronized (MParticle.class) {
if (instance == null) {
sDevicePerformanceMetricsDisabled = options.isDevicePerformanceMetricsDisabled();
sAndroidIdDisabled = options.isAndroidIdDisabled();
sAndroidIdEnabled = options.isAndroidIdEnabled();
setLogLevel(options.getLogLevel());

Context originalContext = context;
Expand Down Expand Up @@ -229,19 +229,37 @@ public static void setInstance(@Nullable MParticle instance) {
}

/**
* Query the status of Android ID collection.
* @deprecated
* This method has been replaced as the behavior has been inverted - Android ID collection is now disabled by default.
* <p> Use {@link androidIdEnabled(boolean)} instead.
*
*
* By default, the SDK will collect <a href="http://developer.android.com/reference/android/provider/Settings.Secure.html#ANDROID_ID">Android Id</a> for the purpose
* of anonymous analytics. If you're not using an mParticle integration that consumes Android ID, the value will be sent to the mParticle
* servers and then immediately discarded. Use this API if you would like to additionally disable it from being collected entirely.
* Query the status of Android ID collection.
*
* By default, the SDK will NOT collect <a href="http://developer.android.com/reference/android/provider/Settings.Secure.html#ANDROID_ID">Android Id</a> for the purpose
* of anonymous analytics. If you're not using an mParticle integration that consumes Android ID and you would like to collect it, use this API to enable collection
*
* @return true if Android ID collection is disabled. (false by default)
* @return false if Android ID collection is enabled. (true by default)
* @see MParticleOptions.Builder#androidIdDisabled(boolean)
* @see MParticleOptions.Builder#androidIdEnabled(boolean)
*/
@Deprecated
public static boolean isAndroidIdDisabled() {
return sAndroidIdDisabled;
return !sAndroidIdEnabled;
}

/**
* Query the status of Android ID collection.
*
* By default, the SDK will NOT collect <a href="http://developer.android.com/reference/android/provider/Settings.Secure.html#ANDROID_ID">Android Id</a> for the purpose
* of anonymous analytics. If you're not using an mParticle integration that consumes Android ID and you would like to collect it, use this API to enable collection.
*
* @return true if Android ID collection is enabled. (false by default)
* @see MParticleOptions.Builder#androidIdEnabled(boolean)
*/
public static boolean isAndroidIdEnabled() {
return sAndroidIdEnabled;
}

/**
Expand Down
56 changes: 45 additions & 11 deletions android-core/src/main/java/com/mparticle/MParticleOptions.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
Expand All @@ -38,7 +37,7 @@ public class MParticleOptions {
private String mApiSecret;
private IdentityApiRequest mIdentifyRequest;
private Boolean mDevicePerformanceMetricsDisabled = false;
private Boolean mAndroidIdDisabled = false;
private Boolean mAndroidIdEnabled = false;
private Integer mUploadInterval = ConfigManager.DEFAULT_UPLOAD_INTERVAL; //seconds
private Integer mSessionTimeout = ConfigManager.DEFAULT_SESSION_TIMEOUT_SECONDS; //seconds
private Integer mConfigMaxAge = null;
Expand Down Expand Up @@ -81,9 +80,11 @@ public MParticleOptions(@NonNull Builder builder) {
if (builder.devicePerformanceMetricsDisabled != null) {
this.mDevicePerformanceMetricsDisabled = builder.devicePerformanceMetricsDisabled;
}
if (builder.androidIdDisabled != null) {
this.mAndroidIdDisabled = builder.androidIdDisabled;
if (builder.androidIdEnabled != null) {
this.mAndroidIdEnabled = builder.androidIdEnabled;
}
Logger.info(String.format("ANDROID_ID will%s be collected based on %s settings", mAndroidIdEnabled ? "" : " not", builder.androidIdEnabled != null ? "MParticleOptions" : "default"));

if (builder.uploadInterval != null) {
if (builder.uploadInterval <= 0) {
Logger.warning("Upload Interval must be a positive number, disregarding value.");
Expand Down Expand Up @@ -203,12 +204,26 @@ public Boolean isDevicePerformanceMetricsDisabled() {
}

/**
* @deprecated
* This method has been replaced as the behavior has been inverted - Android ID collection is now disabled by default.
* <p> Use {@link isAndroidIdEnabled(boolean)} instead.
*
* Query whether Android Id collection is enabled or disabled.
* @return true if collection is disabled, false if it is enabled
*/
@NonNull
@Deprecated
public Boolean isAndroidIdDisabled() {
return mAndroidIdDisabled;
return !mAndroidIdEnabled;
}

/**
* Query whether Android Id collection is enabled or disabled.
* @return true if collection is enabled, false if it is disabled
*/
@NonNull
public Boolean isAndroidIdEnabled() {
return mAndroidIdEnabled;
}

/**
Expand Down Expand Up @@ -330,7 +345,7 @@ public static class Builder {
private MParticle.Environment environment;
private IdentityApiRequest identifyRequest;
private Boolean devicePerformanceMetricsDisabled = null;
private Boolean androidIdDisabled = null;
private Boolean androidIdEnabled = null;
private Integer uploadInterval = null;
private Integer sessionTimeout = null;
private Integer configMaxAge = null;
Expand Down Expand Up @@ -446,17 +461,36 @@ public Builder devicePerformanceMetricsDisabled(boolean disabled) {
}

/**
* By default, the SDK will collect <a href="http://developer.android.com/reference/android/provider/Settings.Secure.html#ANDROID_ID">Android Id</a> for the purpose
* of anonymous analytics. If you're not using an mParticle integration that consumes Android ID, the value will be sent to the mParticle
* servers and then immediately discarded. Use this API if you would like to additionally disable it from being collected entirely.
* @deprecated
* This method has been replaced as the behavior has been inverted - Android ID collection is now disabled by default.
* <p> Use {@link androidIdEnabled(boolean)} instead.
*
*
* By default, the SDK will NOT collect <a href="http://developer.android.com/reference/android/provider/Settings.Secure.html#ANDROID_ID">Android Id</a> for the purpose
* of anonymous analytics. If you're not using an mParticle integration that consumes Android ID and you would like to collect it, use this API to enable collection.
*
* @param disabled true to disable collection (false by default)
* @param disabled false to enable collection (true by default)
*
* @return the instance of the builder, for chaining calls
*/
@NonNull
@Deprecated
public Builder androidIdDisabled(boolean disabled) {
this.androidIdDisabled = disabled;
this.androidIdEnabled = !disabled;
return this;
}

/**
* By default, the SDK will NOT collect <a href="http://developer.android.com/reference/android/provider/Settings.Secure.html#ANDROID_ID">Android Id</a> for the purpose
* of anonymous analytics. If you're not using an mParticle integration that consumes Android ID and you would like to collect it, use this API to enable collection
*
* @param enabled true to enable collection (false by default)
*
* @return the instance of the builder, for chaining calls
*/
@NonNull
public Builder androidIdEnabled(boolean enabled) {
this.androidIdEnabled = enabled;
return this;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public void testMParticleApiVisibility() throws Exception {
publicMethodCount++;
}
}
assertEquals(61, publicMethodCount);
assertEquals(62, publicMethodCount);
}

@Test
Expand Down

0 comments on commit 7fc0217

Please sign in to comment.