Skip to content

Commit b426474

Browse files
liujoshuanrlakin
authored andcommitted
Update user agent header (#11)
* Update Gradle and Android build tools * Fix User-Agent format * This change is required for Bridge to correctly identify platform and app version
1 parent 6c37668 commit b426474

File tree

6 files changed

+154
-7
lines changed

6 files changed

+154
-7
lines changed

app/src/main/java/org/researchstack/sampleapp/SampleDataProvider.java

+8-3
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,13 @@ protected String getStudyId()
4545
}
4646

4747
@Override
48-
protected String getUserAgent()
49-
{
50-
return BuildConfig.STUDY_NAME + "/" + BuildConfig.VERSION_CODE;
48+
protected String getStudyName() {
49+
return BuildConfig.STUDY_NAME;
5150
}
51+
52+
@Override
53+
protected int getAppVersion() {
54+
return BuildConfig.VERSION_CODE;
55+
}
56+
5257
}

app/src/main/java/org/researchstack/sampleapp/bridge/BridgeDataProvider.java

+39-1
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@
22

33
import android.content.Context;
44
import android.content.Intent;
5+
import android.os.Build;
56
import android.support.annotation.NonNull;
67
import android.support.v4.content.LocalBroadcastManager;
8+
import android.text.TextUtils;
79
import android.util.Log;
810
import android.widget.Toast;
911

@@ -99,7 +101,43 @@ public abstract class BridgeDataProvider extends DataProvider
99101

100102
protected abstract String getStudyId();
101103

102-
protected abstract String getUserAgent();
104+
protected final String getUserAgent() {
105+
return getStudyName() + "/" + getAppVersion() + " (" + getDeviceName() + "; Android " + Build.VERSION.RELEASE + ") BridgeSDK/0";
106+
}
107+
108+
protected abstract String getStudyName();
109+
110+
protected abstract int getAppVersion();
111+
112+
private String getDeviceName() {
113+
String manufacturer = Build.MANUFACTURER;
114+
if (TextUtils.isEmpty(manufacturer)){
115+
manufacturer = "Unknown";
116+
}
117+
118+
String model = Build.MODEL;
119+
if(TextUtils.isEmpty(model)){
120+
model = "Android";
121+
}
122+
123+
if (model.startsWith(manufacturer)) {
124+
return capitalize(model);
125+
} else {
126+
return capitalize(manufacturer) + " " + model;
127+
}
128+
}
129+
130+
private String capitalize(String s) {
131+
if (s == null || s.length() == 0) {
132+
return "";
133+
}
134+
char first = s.charAt(0);
135+
if (Character.isUpperCase(first)) {
136+
return s;
137+
} else {
138+
return Character.toUpperCase(first) + s.substring(1);
139+
}
140+
}
103141

104142
public BridgeDataProvider()
105143
{
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package org.researchstack.molemapper;
2+
3+
import android.app.Application;
4+
import android.content.Context;
5+
import android.support.multidex.MultiDex;
6+
7+
import org.researchstack.backbone.storage.database.AppDatabase;
8+
import org.researchstack.skin.ResearchStack;
9+
import org.robolectric.TestLifecycleApplication;
10+
11+
import java.lang.reflect.Method;
12+
13+
import static org.mockito.Mockito.mock;
14+
15+
/**
16+
* Replaces MoleMapperApplication for unit test purposes.
17+
*/
18+
public class TestMoleMapperApplication extends Application implements TestLifecycleApplication {
19+
@Override
20+
public void onCreate() {
21+
super.onCreate();
22+
MultiDex.install(this);
23+
24+
ResearchStack.init(this, new MoleMapperResearchStack() {
25+
@Override
26+
protected AppDatabase createAppDatabaseImplementation(Context context) {
27+
// Used to initialize ResearchStack using a mock AppDatabase. Roboelectric and
28+
// ORMLite do not play nicely
29+
return mock(AppDatabase.class);
30+
}
31+
32+
});
33+
}
34+
35+
@Override
36+
public void beforeTest(Method method) {
37+
38+
}
39+
40+
@Override
41+
public void prepareTest(Object test) {
42+
43+
}
44+
45+
@Override
46+
public void afterTest(Method method) {
47+
48+
}
49+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package org.researchstack.molemapper.bridge;
2+
3+
import android.util.Log;
4+
5+
import static org.junit.Assert.assertTrue;
6+
7+
import org.junit.Before;
8+
import org.junit.Test;
9+
import org.junit.runner.RunWith;
10+
11+
import org.researchstack.molemapper.BuildConfig;
12+
import org.robolectric.RobolectricTestRunner;
13+
import org.robolectric.annotation.Config;
14+
15+
import java.util.regex.Pattern;
16+
17+
18+
/**
19+
* Created by liujoshua on 8/10/16.
20+
*/
21+
@RunWith(RobolectricTestRunner.class)
22+
@Config(constants = BuildConfig.class)
23+
public class BridgeDataProviderTest {
24+
/**
25+
* For example, "App Name/14".
26+
*/
27+
private static final Pattern SHORT_STRING = Pattern.compile("^([^/]+)\\/(\\d{1,9})($)");
28+
/**
29+
* For example, "Unknown Client/14 BridgeJavaSDK/10".
30+
*/
31+
private static final Pattern MEDIUM_STRING = Pattern.compile("^([^/]+)\\/(\\d{1,9})\\s([^/\\(]*)\\/(\\d{1,9})($)");
32+
/**
33+
* For example, "Asthma/26 (Unknown iPhone; iPhone OS 9.1) BridgeSDK/4" or
34+
* "Asthma/26 (Unknown iPhone; iPhone OS/9.1) BridgeSDK/4"
35+
*/
36+
private static final Pattern LONG_STRING = Pattern.compile("^([^/]+)\\/(\\d{1,9})\\s\\(([^;]+);([^\\)]*)\\)\\s([^/]*)\\/(\\d{1,9})($)");
37+
38+
private BridgeDataProvider bridgeDataProvider;
39+
40+
@Before
41+
public void setUp() {
42+
bridgeDataProvider = new MoleMapperDataProvider();
43+
}
44+
45+
@Test
46+
public void testGetUserAgent_MatchesValidFormat() {
47+
String userAgent = bridgeDataProvider.getUserAgent();
48+
49+
boolean isMatchForShortString = SHORT_STRING.matcher(userAgent).matches();
50+
boolean isMatchForMediumString = MEDIUM_STRING.matcher(userAgent).matches();
51+
boolean isMatchForLongString = LONG_STRING.matcher(userAgent).matches();
52+
53+
assertTrue(isMatchForShortString || isMatchForMediumString || isMatchForLongString);
54+
}
55+
}

build.gradle

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ buildscript {
99

1010
dependencies {
1111
// change this to 1.5.x if you're not on Android Studio 2.0.0 beta
12-
classpath 'com.android.tools.build:gradle:2.1.0'
12+
classpath 'com.android.tools.build:gradle:2.1.3'
1313
classpath 'me.tatarka:gradle-retrolambda:3.2.3'
1414
classpath "com.neenbedankt.gradle.plugins:android-apt:1.4"
1515

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
#Mon Dec 28 10:00:20 PST 2015
1+
#Thu Sep 01 21:25:55 PDT 2016
22
distributionBase=GRADLE_USER_HOME
33
distributionPath=wrapper/dists
44
zipStoreBase=GRADLE_USER_HOME
55
zipStorePath=wrapper/dists
6-
distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-all.zip
6+
distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip

0 commit comments

Comments
 (0)