Skip to content

Commit 9b8c951

Browse files
author
Unity Ads Travis
committed
Release 3.0.3
1 parent 0885aed commit 9b8c951

13 files changed

+834
-10
lines changed

Diff for: Jenkinsfile

+93-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,95 @@
1-
@Library('applifier-shared-libs@master') _
1+
pipeline {
2+
agent { label "ads_sdk_worker" }
23

3-
Script {
4-
extraSteps = ['scripts/extra.groovy']
5-
disable_registry = true
4+
stages {
5+
stage('Setup') {
6+
when {
7+
expression { env.BRANCH_NAME =~ /^PR-/ }
8+
}
9+
10+
steps {
11+
dir('sharedLibs') {
12+
checkout(
13+
[$class: 'GitSCM', branches: [[name: 'master']],
14+
userRemoteConfigs: [[credentialsId: 'applifier-readonly-jenkins-bot',
15+
url: 'https://github.com/Applifier/unity-ads-sdk-tests.git']]]
16+
)
17+
script {
18+
sharedLibs = load 'sharedLibs.groovy'
19+
}
20+
}
21+
}
22+
}
23+
24+
stage('Run tests') {
25+
when {
26+
expression { env.BRANCH_NAME =~ /^PR-/ }
27+
}
28+
29+
parallel {
30+
stage ('hybrid_test') {
31+
steps {
32+
dir('results') {
33+
script {
34+
def jobName = "ads-sdk-hybrid-test-android"
35+
def build_ = build(
36+
job: "Applifier/unity-ads-sdk-tests/$jobName",
37+
propagate: false,
38+
wait: true,
39+
parameters: [
40+
string(name: 'UNITY_ADS_ANDROID_BRANCH', value: env.CHANGE_BRANCH),
41+
]
42+
)
43+
44+
def artifactFolder = "$jobName/$build_.number"
45+
dir(jobName) {
46+
sharedLibs.downloadFromGcp("$artifactFolder/*")
47+
}
48+
49+
try {
50+
sharedLibs.removeFromGcp(artifactFolder)
51+
} catch(e) {
52+
echo "Could not clean up artifacts from GCP: '$e'"
53+
}
54+
}
55+
}
56+
}
57+
}
58+
59+
stage('system_test') {
60+
steps {
61+
dir('results') {
62+
script {
63+
def jobName = "ads-sdk-systest-android"
64+
build(
65+
job: "Applifier/unity-ads-sdk-tests/$jobName",
66+
propagate: false,
67+
wait: false,
68+
parameters: [
69+
string(name: 'UNITY_ADS_ANDROID_BRANCH', value: env.CHANGE_BRANCH)
70+
],
71+
)
72+
}
73+
}
74+
}
75+
}
76+
}
77+
}
78+
stage('Post steps') {
79+
when {
80+
expression { env.BRANCH_NAME =~ /^PR-/ }
81+
}
82+
83+
steps {
84+
script {
85+
archiveArtifacts artifacts: "results/**", fingerprint: true
86+
step ([$class: "JUnitResultArchiver", testResults: "results/**/*.xml"])
87+
script {
88+
slackChannel = "ads-sdk-notify"
89+
sharedLibs.sendTestSummary(slackChannel)
90+
}
91+
}
92+
}
93+
}
94+
}
695
}

Diff for: app/build.gradle

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ android {
88
applicationId "com.unity3d.ads.example"
99
minSdkVersion 14
1010
targetSdkVersion 26
11-
versionCode = 3000
12-
versionName = "3.0.0"
11+
versionCode = 3003
12+
versionName = "3.0.3"
1313
}
1414

1515
flavorDimensions "arEnabled"

Diff for: lib/build.gradle

+2-2
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ android {
2121
All SDK with version numbers with last two digits >= 50 will be treated
2222
as China SDK for filtering in the backend.
2323
*/
24-
versionCode = 3001
25-
versionName = "3.0.1"
24+
versionCode = 3003
25+
versionName = "3.0.3"
2626

2727
setProperty("archivesBaseName", "unity-ads")
2828

Diff for: lib/src/main/java/com/unity3d/services/core/configuration/Configuration.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@ public class Configuration {
3636
"com.unity3d.services.purchasing.core.configuration.PurchasingModuleConfiguration",
3737
"com.unity3d.services.analytics.core.configuration.AnalyticsModuleConfiguration",
3838
"com.unity3d.services.ar.configuration.ARModuleConfiguration",
39-
"com.unity3d.services.banners.configuration.BannersModuleConfiguration"
39+
"com.unity3d.services.banners.configuration.BannersModuleConfiguration",
40+
"com.unity3d.services.store.core.configuration.StoreModuleConfiguration"
4041
};
4142

4243
private Class[] _webAppApiClassList;

Diff for: lib/src/main/java/com/unity3d/services/core/webview/WebViewEventCategory.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,6 @@ public enum WebViewEventCategory {
1616
PURCHASING,
1717
ANALYTICS,
1818
AR,
19-
PERMISSIONS
19+
PERMISSIONS,
20+
STORE
2021
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
1+
package com.unity3d.services.store;
2+
3+
import android.content.Context;
4+
import android.os.Bundle;
5+
import android.os.IBinder;
6+
7+
import com.unity3d.services.core.log.DeviceLog;
8+
import com.unity3d.services.core.properties.ClientProperties;
9+
import com.unity3d.services.store.core.StoreException;
10+
11+
import org.json.JSONArray;
12+
import org.json.JSONException;
13+
import org.json.JSONObject;
14+
15+
import java.lang.reflect.InvocationTargetException;
16+
import java.lang.reflect.Method;
17+
import java.util.ArrayList;
18+
19+
public class StoreBilling {
20+
public static Object asInterface(Context context, IBinder service) {
21+
Object[] args = new Object[] { service };
22+
23+
Class billingServiceStub;
24+
25+
try {
26+
billingServiceStub = Class.forName("com.android.vending.billing.IInAppBillingService$Stub");
27+
} catch (ClassNotFoundException e) {
28+
DeviceLog.exception("Billing service stub not found", e);
29+
return null;
30+
}
31+
32+
Method asInterface;
33+
34+
try {
35+
asInterface = billingServiceStub.getMethod("asInterface", IBinder.class);
36+
} catch (NoSuchMethodException e) {
37+
DeviceLog.exception("asInterface method not found", e);
38+
return null;
39+
}
40+
41+
try {
42+
return asInterface.invoke(null, service);
43+
} catch (IllegalAccessException e) {
44+
DeviceLog.exception("Illegal access exception while invoking asInterface", e);
45+
} catch (InvocationTargetException e) {
46+
DeviceLog.exception("Invocation target exception while invoking asInterface", e);
47+
}
48+
49+
return null;
50+
}
51+
52+
public static int isBillingSupported(Context context, Object billingServiceObject, String purchaseType) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, StoreException {
53+
Class billingService = Class.forName("com.android.vending.billing.IInAppBillingService");
54+
Method isBillingSupported = billingService.getMethod("isBillingSupported", Integer.TYPE, String.class, String.class);
55+
56+
Object result = isBillingSupported.invoke(billingServiceObject, 3, ClientProperties.getAppName(), purchaseType);
57+
58+
if(result != null) {
59+
return (int) result;
60+
}
61+
62+
throw new StoreException();
63+
}
64+
65+
public static JSONObject getPurchases(Context context, Object billingServiceObject, String purchaseType) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, JSONException, StoreException {
66+
Class billingService = Class.forName("com.android.vending.billing.IInAppBillingService");
67+
Method getPurchases = billingService.getMethod("getPurchases", Integer.TYPE, String.class, String.class, String.class);
68+
69+
JSONObject resultObject = new JSONObject();
70+
JSONArray purchaseDataArray = new JSONArray();
71+
JSONArray signatureArray = new JSONArray();
72+
JSONArray productArray = new JSONArray();
73+
String continuationToken = null;
74+
75+
do {
76+
Object result = getPurchases.invoke(billingServiceObject, 3, ClientProperties.getAppName(), purchaseType, continuationToken);
77+
continuationToken = null;
78+
79+
if(result instanceof Bundle) {
80+
Bundle resultBundle = (Bundle) result;
81+
82+
int responseCode = resultBundle.getInt("RESPONSE_CODE");
83+
DeviceLog.debug("getPurchases responds with code " + responseCode);
84+
85+
if(responseCode == 0) {
86+
ArrayList<String> purchaseDataList = resultBundle.getStringArrayList("INAPP_PURCHASE_DATA_LIST");
87+
for(String purchase : purchaseDataList) {
88+
purchaseDataArray.put(new JSONObject(purchase));
89+
}
90+
91+
ArrayList<String> signatureList = resultBundle.getStringArrayList("INAPP_DATA_SIGNATURE_LIST");
92+
for(String signature : signatureList) {
93+
signatureArray.put(signature);
94+
}
95+
96+
ArrayList<String> productList = resultBundle.getStringArrayList("INAPP_PURCHASE_ITEM_LIST");
97+
for(String product : productList) {
98+
productArray.put(product);
99+
}
100+
101+
continuationToken = resultBundle.getString("INAPP_CONTINUATION_TOKEN");
102+
} else {
103+
throw new StoreException(responseCode);
104+
}
105+
} else {
106+
throw new StoreException();
107+
}
108+
} while(continuationToken != null);
109+
110+
resultObject.put("purchaseDataList", purchaseDataArray);
111+
resultObject.put("signatureList", signatureArray);
112+
resultObject.put("purchaseItemList", productArray);
113+
114+
return resultObject;
115+
}
116+
117+
public static JSONObject getPurchaseHistory(Context context, Object billingServiceObject, String purchaseType, int maxPurchases) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, JSONException, StoreException {
118+
Class billingService = Class.forName("com.android.vending.billing.IInAppBillingService");
119+
Method getPurchaseHistory = billingService.getMethod("getPurchaseHistory", Integer.TYPE, String.class, String.class, String.class, Bundle.class);
120+
121+
JSONObject resultObject = new JSONObject();
122+
JSONArray purchaseDataArray = new JSONArray();
123+
JSONArray signatureArray = new JSONArray();
124+
JSONArray productArray = new JSONArray();
125+
126+
String continuationToken = null;
127+
int purchaseCount = 0;
128+
129+
do {
130+
Object result = getPurchaseHistory.invoke(billingServiceObject, 6, ClientProperties.getAppName(), purchaseType, continuationToken, new Bundle());
131+
continuationToken = null;
132+
133+
if(result instanceof Bundle) {
134+
Bundle resultBundle = (Bundle) result;
135+
136+
int responseCode = resultBundle.getInt("RESPONSE_CODE");
137+
138+
if(responseCode == 0) {
139+
ArrayList<String> purchaseDataList = resultBundle.getStringArrayList("INAPP_PURCHASE_DATA_LIST");
140+
for(String purchase : purchaseDataList) {
141+
purchaseDataArray.put(new JSONObject(purchase));
142+
purchaseCount++;
143+
}
144+
145+
ArrayList<String> signatureList = resultBundle.getStringArrayList("INAPP_DATA_SIGNATURE_LIST");
146+
for(String signature : signatureList) {
147+
signatureArray.put(signature);
148+
}
149+
150+
ArrayList<String> productList = resultBundle.getStringArrayList("INAPP_PURCHASE_ITEM_LIST");
151+
for(String product : productList) {
152+
productArray.put(product);
153+
}
154+
155+
continuationToken = resultBundle.getString("INAPP_CONTINUATION_TOKEN");
156+
} else {
157+
throw new StoreException(responseCode);
158+
}
159+
} else {
160+
throw new StoreException();
161+
}
162+
} while(continuationToken != null && (maxPurchases == 0 || purchaseCount < maxPurchases));
163+
164+
resultObject.put("purchaseDataList", purchaseDataArray);
165+
resultObject.put("signatureList", signatureArray);
166+
resultObject.put("purchaseItemList", productArray);
167+
168+
return resultObject;
169+
}
170+
171+
public static JSONArray getSkuDetails(Context context, Object billingServiceObject, String purchaseType, ArrayList<String> skuList) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, StoreException, JSONException {
172+
Class billingService = Class.forName("com.android.vending.billing.IInAppBillingService");
173+
Method getSkuDetails = billingService.getMethod("getSkuDetails", Integer.TYPE, String.class, String.class, Bundle.class);
174+
175+
Bundle args = new Bundle();
176+
args.putStringArrayList("ITEM_ID_LIST", skuList);
177+
178+
Object result = getSkuDetails.invoke(billingServiceObject, 3, ClientProperties.getAppName(), purchaseType, args);
179+
180+
JSONArray resultArray = new JSONArray();
181+
182+
if(result instanceof Bundle) {
183+
Bundle resultBundle = (Bundle) result;
184+
185+
int responseCode = resultBundle.getInt("RESPONSE_CODE");
186+
187+
if(responseCode == 0) {
188+
ArrayList<String> detailsList = resultBundle.getStringArrayList("DETAILS_LIST");
189+
190+
for(String detail : detailsList) {
191+
resultArray.put(new JSONObject(detail));
192+
}
193+
} else {
194+
throw new StoreException(responseCode);
195+
}
196+
} else {
197+
throw new StoreException();
198+
}
199+
200+
return resultArray;
201+
}
202+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package com.unity3d.services.store;
2+
3+
public enum StoreError {
4+
NOT_INITIALIZED,
5+
CLASS_NOT_FOUND,
6+
NO_SUCH_METHOD,
7+
INVOCATION_TARGET,
8+
ILLEGAL_ACCESS,
9+
JSON_ERROR,
10+
STORE_ERROR,
11+
UNKNOWN_ERROR
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package com.unity3d.services.store;
2+
3+
public enum StoreEvent {
4+
INITIALIZED,
5+
INITIALIZATION_FAILED,
6+
DISCONNECTED,
7+
PURCHASE_STATUS_ON_RESUME,
8+
PURCHASE_STATUS_ON_STOP,
9+
PURCHASE_STATUS_ON_RESUME_ERROR,
10+
PURCHASE_STATUS_ON_STOP_ERROR,
11+
GETPURCHASES_RESULT,
12+
GETPURCHASES_ERROR,
13+
PURCHASE_HISTORY_RESULT,
14+
PURCHASE_HISTORY_ERROR,
15+
SKU_DETAILS_RESULT,
16+
SKU_DETAILS_ERROR,
17+
BILLING_SUPPORTED_RESULT,
18+
BILLING_SUPPORTED_ERROR
19+
}

0 commit comments

Comments
 (0)