Skip to content

Commit

Permalink
Release 3.0.3
Browse files Browse the repository at this point in the history
  • Loading branch information
Unity Ads Travis committed Mar 22, 2019
1 parent 0885aed commit 9b8c951
Show file tree
Hide file tree
Showing 13 changed files with 834 additions and 10 deletions.
97 changes: 93 additions & 4 deletions Jenkinsfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,95 @@
@Library('applifier-shared-libs@master') _
pipeline {
agent { label "ads_sdk_worker" }

Script {
extraSteps = ['scripts/extra.groovy']
disable_registry = true
stages {
stage('Setup') {
when {
expression { env.BRANCH_NAME =~ /^PR-/ }
}

steps {
dir('sharedLibs') {
checkout(
[$class: 'GitSCM', branches: [[name: 'master']],
userRemoteConfigs: [[credentialsId: 'applifier-readonly-jenkins-bot',
url: 'https://github.com/Applifier/unity-ads-sdk-tests.git']]]
)
script {
sharedLibs = load 'sharedLibs.groovy'
}
}
}
}

stage('Run tests') {
when {
expression { env.BRANCH_NAME =~ /^PR-/ }
}

parallel {
stage ('hybrid_test') {
steps {
dir('results') {
script {
def jobName = "ads-sdk-hybrid-test-android"
def build_ = build(
job: "Applifier/unity-ads-sdk-tests/$jobName",
propagate: false,
wait: true,
parameters: [
string(name: 'UNITY_ADS_ANDROID_BRANCH', value: env.CHANGE_BRANCH),
]
)

def artifactFolder = "$jobName/$build_.number"
dir(jobName) {
sharedLibs.downloadFromGcp("$artifactFolder/*")
}

try {
sharedLibs.removeFromGcp(artifactFolder)
} catch(e) {
echo "Could not clean up artifacts from GCP: '$e'"
}
}
}
}
}

stage('system_test') {
steps {
dir('results') {
script {
def jobName = "ads-sdk-systest-android"
build(
job: "Applifier/unity-ads-sdk-tests/$jobName",
propagate: false,
wait: false,
parameters: [
string(name: 'UNITY_ADS_ANDROID_BRANCH', value: env.CHANGE_BRANCH)
],
)
}
}
}
}
}
}
stage('Post steps') {
when {
expression { env.BRANCH_NAME =~ /^PR-/ }
}

steps {
script {
archiveArtifacts artifacts: "results/**", fingerprint: true
step ([$class: "JUnitResultArchiver", testResults: "results/**/*.xml"])
script {
slackChannel = "ads-sdk-notify"
sharedLibs.sendTestSummary(slackChannel)
}
}
}
}
}
}
4 changes: 2 additions & 2 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ android {
applicationId "com.unity3d.ads.example"
minSdkVersion 14
targetSdkVersion 26
versionCode = 3000
versionName = "3.0.0"
versionCode = 3003
versionName = "3.0.3"
}

flavorDimensions "arEnabled"
Expand Down
4 changes: 2 additions & 2 deletions lib/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ android {
All SDK with version numbers with last two digits >= 50 will be treated
as China SDK for filtering in the backend.
*/
versionCode = 3001
versionName = "3.0.1"
versionCode = 3003
versionName = "3.0.3"

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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ public class Configuration {
"com.unity3d.services.purchasing.core.configuration.PurchasingModuleConfiguration",
"com.unity3d.services.analytics.core.configuration.AnalyticsModuleConfiguration",
"com.unity3d.services.ar.configuration.ARModuleConfiguration",
"com.unity3d.services.banners.configuration.BannersModuleConfiguration"
"com.unity3d.services.banners.configuration.BannersModuleConfiguration",
"com.unity3d.services.store.core.configuration.StoreModuleConfiguration"
};

private Class[] _webAppApiClassList;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,6 @@ public enum WebViewEventCategory {
PURCHASING,
ANALYTICS,
AR,
PERMISSIONS
PERMISSIONS,
STORE
}
202 changes: 202 additions & 0 deletions lib/src/main/java/com/unity3d/services/store/StoreBilling.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
package com.unity3d.services.store;

import android.content.Context;
import android.os.Bundle;
import android.os.IBinder;

import com.unity3d.services.core.log.DeviceLog;
import com.unity3d.services.core.properties.ClientProperties;
import com.unity3d.services.store.core.StoreException;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;

public class StoreBilling {
public static Object asInterface(Context context, IBinder service) {
Object[] args = new Object[] { service };

Class billingServiceStub;

try {
billingServiceStub = Class.forName("com.android.vending.billing.IInAppBillingService$Stub");
} catch (ClassNotFoundException e) {
DeviceLog.exception("Billing service stub not found", e);
return null;
}

Method asInterface;

try {
asInterface = billingServiceStub.getMethod("asInterface", IBinder.class);
} catch (NoSuchMethodException e) {
DeviceLog.exception("asInterface method not found", e);
return null;
}

try {
return asInterface.invoke(null, service);
} catch (IllegalAccessException e) {
DeviceLog.exception("Illegal access exception while invoking asInterface", e);
} catch (InvocationTargetException e) {
DeviceLog.exception("Invocation target exception while invoking asInterface", e);
}

return null;
}

public static int isBillingSupported(Context context, Object billingServiceObject, String purchaseType) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, StoreException {
Class billingService = Class.forName("com.android.vending.billing.IInAppBillingService");
Method isBillingSupported = billingService.getMethod("isBillingSupported", Integer.TYPE, String.class, String.class);

Object result = isBillingSupported.invoke(billingServiceObject, 3, ClientProperties.getAppName(), purchaseType);

if(result != null) {
return (int) result;
}

throw new StoreException();
}

public static JSONObject getPurchases(Context context, Object billingServiceObject, String purchaseType) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, JSONException, StoreException {
Class billingService = Class.forName("com.android.vending.billing.IInAppBillingService");
Method getPurchases = billingService.getMethod("getPurchases", Integer.TYPE, String.class, String.class, String.class);

JSONObject resultObject = new JSONObject();
JSONArray purchaseDataArray = new JSONArray();
JSONArray signatureArray = new JSONArray();
JSONArray productArray = new JSONArray();
String continuationToken = null;

do {
Object result = getPurchases.invoke(billingServiceObject, 3, ClientProperties.getAppName(), purchaseType, continuationToken);
continuationToken = null;

if(result instanceof Bundle) {
Bundle resultBundle = (Bundle) result;

int responseCode = resultBundle.getInt("RESPONSE_CODE");
DeviceLog.debug("getPurchases responds with code " + responseCode);

if(responseCode == 0) {
ArrayList<String> purchaseDataList = resultBundle.getStringArrayList("INAPP_PURCHASE_DATA_LIST");
for(String purchase : purchaseDataList) {
purchaseDataArray.put(new JSONObject(purchase));
}

ArrayList<String> signatureList = resultBundle.getStringArrayList("INAPP_DATA_SIGNATURE_LIST");
for(String signature : signatureList) {
signatureArray.put(signature);
}

ArrayList<String> productList = resultBundle.getStringArrayList("INAPP_PURCHASE_ITEM_LIST");
for(String product : productList) {
productArray.put(product);
}

continuationToken = resultBundle.getString("INAPP_CONTINUATION_TOKEN");
} else {
throw new StoreException(responseCode);
}
} else {
throw new StoreException();
}
} while(continuationToken != null);

resultObject.put("purchaseDataList", purchaseDataArray);
resultObject.put("signatureList", signatureArray);
resultObject.put("purchaseItemList", productArray);

return resultObject;
}

public static JSONObject getPurchaseHistory(Context context, Object billingServiceObject, String purchaseType, int maxPurchases) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, JSONException, StoreException {
Class billingService = Class.forName("com.android.vending.billing.IInAppBillingService");
Method getPurchaseHistory = billingService.getMethod("getPurchaseHistory", Integer.TYPE, String.class, String.class, String.class, Bundle.class);

JSONObject resultObject = new JSONObject();
JSONArray purchaseDataArray = new JSONArray();
JSONArray signatureArray = new JSONArray();
JSONArray productArray = new JSONArray();

String continuationToken = null;
int purchaseCount = 0;

do {
Object result = getPurchaseHistory.invoke(billingServiceObject, 6, ClientProperties.getAppName(), purchaseType, continuationToken, new Bundle());
continuationToken = null;

if(result instanceof Bundle) {
Bundle resultBundle = (Bundle) result;

int responseCode = resultBundle.getInt("RESPONSE_CODE");

if(responseCode == 0) {
ArrayList<String> purchaseDataList = resultBundle.getStringArrayList("INAPP_PURCHASE_DATA_LIST");
for(String purchase : purchaseDataList) {
purchaseDataArray.put(new JSONObject(purchase));
purchaseCount++;
}

ArrayList<String> signatureList = resultBundle.getStringArrayList("INAPP_DATA_SIGNATURE_LIST");
for(String signature : signatureList) {
signatureArray.put(signature);
}

ArrayList<String> productList = resultBundle.getStringArrayList("INAPP_PURCHASE_ITEM_LIST");
for(String product : productList) {
productArray.put(product);
}

continuationToken = resultBundle.getString("INAPP_CONTINUATION_TOKEN");
} else {
throw new StoreException(responseCode);
}
} else {
throw new StoreException();
}
} while(continuationToken != null && (maxPurchases == 0 || purchaseCount < maxPurchases));

resultObject.put("purchaseDataList", purchaseDataArray);
resultObject.put("signatureList", signatureArray);
resultObject.put("purchaseItemList", productArray);

return resultObject;
}

public static JSONArray getSkuDetails(Context context, Object billingServiceObject, String purchaseType, ArrayList<String> skuList) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, StoreException, JSONException {
Class billingService = Class.forName("com.android.vending.billing.IInAppBillingService");
Method getSkuDetails = billingService.getMethod("getSkuDetails", Integer.TYPE, String.class, String.class, Bundle.class);

Bundle args = new Bundle();
args.putStringArrayList("ITEM_ID_LIST", skuList);

Object result = getSkuDetails.invoke(billingServiceObject, 3, ClientProperties.getAppName(), purchaseType, args);

JSONArray resultArray = new JSONArray();

if(result instanceof Bundle) {
Bundle resultBundle = (Bundle) result;

int responseCode = resultBundle.getInt("RESPONSE_CODE");

if(responseCode == 0) {
ArrayList<String> detailsList = resultBundle.getStringArrayList("DETAILS_LIST");

for(String detail : detailsList) {
resultArray.put(new JSONObject(detail));
}
} else {
throw new StoreException(responseCode);
}
} else {
throw new StoreException();
}

return resultArray;
}
}
12 changes: 12 additions & 0 deletions lib/src/main/java/com/unity3d/services/store/StoreError.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.unity3d.services.store;

public enum StoreError {
NOT_INITIALIZED,
CLASS_NOT_FOUND,
NO_SUCH_METHOD,
INVOCATION_TARGET,
ILLEGAL_ACCESS,
JSON_ERROR,
STORE_ERROR,
UNKNOWN_ERROR
}
19 changes: 19 additions & 0 deletions lib/src/main/java/com/unity3d/services/store/StoreEvent.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.unity3d.services.store;

public enum StoreEvent {
INITIALIZED,
INITIALIZATION_FAILED,
DISCONNECTED,
PURCHASE_STATUS_ON_RESUME,
PURCHASE_STATUS_ON_STOP,
PURCHASE_STATUS_ON_RESUME_ERROR,
PURCHASE_STATUS_ON_STOP_ERROR,
GETPURCHASES_RESULT,
GETPURCHASES_ERROR,
PURCHASE_HISTORY_RESULT,
PURCHASE_HISTORY_ERROR,
SKU_DETAILS_RESULT,
SKU_DETAILS_ERROR,
BILLING_SUPPORTED_RESULT,
BILLING_SUPPORTED_ERROR
}
Loading

0 comments on commit 9b8c951

Please sign in to comment.