Skip to content

Commit

Permalink
Merge remote-tracking branch 'mParticle/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
sojanpr committed Mar 30, 2018
2 parents 21d13af + 20f2903 commit bc70da5
Show file tree
Hide file tree
Showing 119 changed files with 4,468 additions and 1,263 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,6 @@ local.properties
# Gradle
build
.gradle

#test results
/testResults
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Copyright 2015 mParticle, Inc.
Copyright 2018 mParticle, Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down
30 changes: 24 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ You can grab the Core SDK via Maven Central. Please reference the badge above an

```groovy
dependencies {
implementation 'com.mparticle:android-core:5.0.10'
implementation 'com.mparticle:android-core:5.2.1'
}
```

Expand All @@ -27,8 +27,8 @@ Several integrations require additional client-side add-on libraries called "kit
```groovy
dependencies {
implementation (
'com.mparticle:android-example-kit:5.0.10',
'com.mparticle:android-another-kit:5.0.10'
'com.mparticle:android-example-kit:5.2.1',
'com.mparticle:android-another-kit:5.2.1'
)
}
```
Expand Down Expand Up @@ -80,13 +80,31 @@ mParticle supports several marketing automation and push messaging integrations.
implementation 'com.google.firebase:firebase-messaging:11.6.2'
```

### Google Play Install Referrer
## Google Play Install Referrer

#### Single Receiver
In order for attribution, deep linking, and many other integrations to work properly, the mParticle SDK collects the Google Play Install referrer string, which tracks the original link that brought the user to Google Play.

There are two different ways to collect this value - you only need to implement one.

### 1. Play Install Referrer Library

Google now supports a [library that surface the referrer string](https://developer.android.com/google/play/installreferrer/library.html):

Simply add this dependency to your app and the mParticle SDK will detect it:

```groovy
implementation 'com.android.installreferrer:installreferrer:1.0'
```

### 2. Broadcast Receivers

In order for attribution, deep linking, and many other integrations to work properly, add the mParticle `ReferrerReceiver` to your manifest file within the `<application>` tag. The mParticle SDK
Alternatively, you can add the mParticle `ReferrerReceiver` to your manifest file within the `<application>` tag. The mParticle SDK
will collect any campaign referral information and automatically forward it to kits (such as AppsFlyer, Kochava, and Adjust) and server-side integrations.

#### Single Receiver

If you have no other `BroadcastReceiver` that listens for the `INSTALL_REFERRER` intent, you can just add the mParticle receiver:

```xml
<receiver android:name="com.mparticle.ReferrerReceiver" android:exported="true">
<intent-filter>
Expand Down
46 changes: 43 additions & 3 deletions android-core/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ apply from: '../scripts/maven.gradle'
android {
compileSdkVersion 26
buildToolsVersion "26.0.2"
packagingOptions {
exclude 'META-INF/LICENSE'
}

compileOptions {
sourceCompatibility JavaVersion.VERSION_1_6
Expand Down Expand Up @@ -39,7 +42,7 @@ android {
if (properties.stringPropertyNames().contains('mp.configurl')) {
configurationUrl = properties.getProperty('mp.configurl')
}
}catch (Exception e){
} catch (Exception e) {

}

Expand All @@ -48,6 +51,8 @@ android {
if (gitHash == null || gitHash.length() == 0) {
gitHash = System.getenv("MP_GIT_SHA").substring(0, 7)
}

testBuildType obtainTestBuildType()

defaultConfig {
minSdkVersion 9
Expand All @@ -60,6 +65,7 @@ android {
buildConfigField "String", "MP_IDENTITY_URL", identityUrl
buildConfigField "String", "MP_CONFIG_URL", configurationUrl
buildConfigField "Boolean", "MP_DEBUG", "false"
buildConfigField "String", "SCHEMA", "\"https\""

testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
Expand All @@ -68,16 +74,27 @@ android {
debug {
minifyEnabled false
buildConfigField "Boolean", "MP_DEBUG", "true"
multiDexEnabled true
}
release {
minifyEnabled true
proguardFiles 'proguard.pro'

consumerProguardFiles 'consumer-proguard.pro'
//buildConfigField "Boolean", "MP_DEBUG", "true"
// buildConfigField "Boolean", "MP_DEBUG", "true"
}
instrumented {
minifyEnabled false
debuggable true
buildConfigField "String", "MP_URL", "\"localhost:8080\""
buildConfigField "String", "MP_CONFIG_URL", "\"localhost:8080\""
buildConfigField "String", "MP_IDENTITY_URL", "\"localhost:8080\""
buildConfigField "String", "SCHEMA", "\"http\""
buildConfigField "Boolean", "MP_DEBUG", "false"
signingConfig signingConfigs.debug
multiDexEnabled true
}
}

}

task coreSdkJavadocs(type: Javadoc) {
Expand All @@ -100,6 +117,8 @@ dependencies {
compileOnly 'com.google.firebase:firebase-messaging:[7.0,)'
compileOnly 'com.android.support:support-v4:[26.0, )'
compileOnly 'com.android.installreferrer:installreferrer:[1.0, )'
compileOnly 'com.google.android.instantapps:instantapps:[1.0, )'

testImplementation 'junit:junit:4.12'
testImplementation files('libs/java-json.jar')
testImplementation 'org.powermock:powermock-module-junit4:1.6.2'
Expand All @@ -110,9 +129,19 @@ dependencies {
androidTestImplementation 'com.android.support:support-annotations:24.0.0'
androidTestImplementation 'com.android.support.test:runner:1.0.1'
androidTestImplementation 'com.android.support.test:rules:1.0.1'
androidTestImplementation 'org.apache.httpcomponents:httpclient-android:4.3.5.1'
androidTestImplementation 'org.slf4j:slf4j-api:1.7.12'
androidTestImplementation('org.mockito:mockito-core:1+'){
exclude group: 'junit' exclude group: 'org.hamcrest', module: 'hamcrest-core'
}
androidTestImplementation("com.github.tomakehurst:wiremock:2.8.0") {

exclude group: 'org.apache.httpcomponents', module: 'httpclient'
exclude group: 'org.slf4j', module: 'slf4j-api'
exclude group: 'org.ow2.asm', module: 'asm'
exclude group: 'org.json', module: 'json'
}
androidTestImplementation 'org.hamcrest:hamcrest-library:1.3'
}

configurations {
Expand Down Expand Up @@ -140,3 +169,14 @@ project.afterEvaluate {
def compileLintTask = project.tasks.find { it.name == 'compileLint' }
compileLintTask.dependsOn(copyLintJar)
}


def obtainTestBuildType() {
def result = "instrumented";

if (project.hasProperty("testBuildType")) {
result = project.getProperties().get("testBuildType")
}

result
}
6 changes: 3 additions & 3 deletions android-core/proguard.pro
Original file line number Diff line number Diff line change
Expand Up @@ -121,10 +121,10 @@
-keep, includedescriptorclasses class com.mparticle.identity.IdentityStateListener { *; }
-keep, includedescriptorclasses public class com.mparticle.identity.* { *; }
-keep class com.mparticle.internal.BackgroundTaskHandler { *; }
-keep class com.mparticle.ConsentEvent { *; }
-keep class com.mparticle.ConsentEvent$Builder { *; }
-keep, includedescriptorclasses class com.mparticle.ConsentEvent$Builder { *; }

-keep public class com.mparticle.activity.* {
*;
}

-keep public class com.mparticle.messaging.* {
*;
Expand Down
1 change: 1 addition & 0 deletions android-core/src/androidTest/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

<application />
</manifest>
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,8 @@ public class AccessUtils {
public static MessageManager getMessageManager() {
return MParticle.getInstance().mMessageManager;
}

public static void logEvent(ConsentEvent consentEvent) {
MParticle.getInstance().logEvent(consentEvent);
}
}
Original file line number Diff line number Diff line change
@@ -1,28 +1,57 @@
package com.mparticle;

import android.app.Activity;
import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.support.test.InstrumentationRegistry;
import android.util.Log;

import com.github.tomakehurst.wiremock.common.Notifier;
import com.mparticle.commerce.Product;
import com.mparticle.internal.AccessUtils;
import com.mparticle.internal.AppStateManager;

import com.github.tomakehurst.wiremock.WireMockServer;
import com.mparticle.utils.Server;

import org.json.JSONException;
import org.json.JSONObject;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;

import static junit.framework.Assert.fail;
import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
import static com.github.tomakehurst.wiremock.client.WireMock.equalToJson;
import static com.github.tomakehurst.wiremock.client.WireMock.get;
import static com.github.tomakehurst.wiremock.client.WireMock.matchingJsonPath;
import static com.github.tomakehurst.wiremock.client.WireMock.post;
import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
import static com.github.tomakehurst.wiremock.client.WireMock.urlPathMatching;
import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig;

public abstract class BaseAbstractTest {
protected static Context mContext;

protected static Server mServer;
private static boolean beforeClassCalled = false;
protected Context mContext;

@BeforeClass
public static void beforeClassImpl() {
if (Looper.myLooper() == null) {
Looper.prepare();
}

}

@Before
public void beforeImpl() throws Exception {
if (mServer == null) {
mServer = new Server();
} else {
mServer.reset();
}
mContext = InstrumentationRegistry.getContext();
if (!beforeClassCalled) {
beforeClassCalled = true;
beforeClassBase();
Expand All @@ -33,9 +62,36 @@ public void beforeImpl() throws Exception {
before();
}

@AfterClass
public static void afterClassImpl() {
beforeClassCalled = false;
mServer.stop();
}

protected abstract void beforeClassBase() throws Exception;
protected abstract void beforeClass() throws Exception;
protected abstract void beforeBase() throws Exception;
protected abstract void before() throws Exception;

Activity activity = new Activity();

protected void goToBackground() {
if (MParticle.getInstance() != null) {
AppStateManager appStateManager = MParticle.getInstance().getAppStateManager();
//need to set AppStateManager's Handler to be on the main looper, otherwise, it will not put the app in the background
AccessUtils.setAppStateManagerHandler(new Handler(Looper.getMainLooper()));
if (appStateManager.isBackgrounded()) {
appStateManager.onActivityResumed(activity);
}
appStateManager.onActivityPaused(activity);
}
}

protected void goToForeground() {
activity = new Activity();
if (MParticle.getInstance() != null) {
AppStateManager appStateManager = MParticle.getInstance().getAppStateManager();
appStateManager.onActivityResumed(activity);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

import com.mparticle.utils.MParticleUtils;

/**
* Base class that will replicate the scenario or an app that has started, but has not called
* MParticle.start(). This base class is useful for testing initialization behavior.
*/
abstract public class BaseCleanInstallEachTest extends BaseAbstractTest {

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,31 @@
package com.mparticle;

import android.content.Context;
import android.support.test.InstrumentationRegistry;
import android.util.Log;

import com.mparticle.identity.AccessUtils;
import com.mparticle.identity.AccessUtils.IdentityApiClient;
import com.mparticle.internal.AppStateManager;
import com.mparticle.internal.ConfigManager;
import com.mparticle.internal.Constants;
import com.mparticle.utils.MParticleUtils;

import java.util.Random;
import java.util.concurrent.CountDownLatch;

import static junit.framework.Assert.assertNull;
import static junit.framework.Assert.fail;


/**
* Base class that will replicate the scenario that MParticle has been started and is running. This
* state also includes the initial IdentityApi.Identify call has completed.
*
* That being said, there is no need to call MParticle.start() in your before or beforeClass methods,
* or in your tests.
*
* If you want to test the behavior that occures during initialization, you should either invoke
* MParticle.setInstance(null), or use BaseCleanInstallEachTest as your base class
*/
public abstract class BaseCleanStartedEachTest extends BaseAbstractTest {
protected static Long mStartingMpid;

Expand All @@ -22,23 +35,22 @@ protected void beforeClassBase() throws Exception {
}

@Override
public void beforeBase() {
public void beforeBase() throws InterruptedException {
MParticleUtils.clear();
mStartingMpid = new Random().nextLong();
final CountDownLatch latch = new CountDownLatch(1);
new ConfigManager(mContext, null, null, null).setMpid(mStartingMpid);
mServer.setupHappyIdentify(mStartingMpid);
MParticle.setInstance(null);
MParticleOptions options = MParticleOptions
.builder(mContext)
.credentials("key", "value")
.build();
AccessUtils.setIdentityApiClient(new IdentityApiClient(latch), true);
MParticle.start(options);
try {
latch.await();
} catch (InterruptedException e) {
fail(e.getMessage());
}
AccessUtils.clearIdentityApiClient();
MParticle.getInstance().getConfigManager().setMpid(mStartingMpid);
AppStateManager.mInitialized = false;
Thread.sleep(3000);
}

protected void setMpidAfterInitialIdentityCall(long mpid) {
mServer.addConditionalIdentityResponse(mStartingMpid, mpid);
}
}
14 changes: 14 additions & 0 deletions android-core/src/androidTest/java/com/mparticle/BaseTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.mparticle;

public abstract class BaseTest extends BaseAbstractTest {

@Override
protected void beforeClassBase() throws Exception {

}

@Override
protected void beforeBase() throws Exception {

}
}
Loading

0 comments on commit bc70da5

Please sign in to comment.