Release 3.0.3
This commit is contained in:
Родитель
0885aed0c5
Коммит
9b8c951ebe
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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")
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -16,5 +16,6 @@ public enum WebViewEventCategory {
|
|||
PURCHASING,
|
||||
ANALYTICS,
|
||||
AR,
|
||||
PERMISSIONS
|
||||
PERMISSIONS,
|
||||
STORE
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
package com.unity3d.services.store;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.Activity;
|
||||
import android.app.Application;
|
||||
import android.os.Bundle;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
@TargetApi(14)
|
||||
public class StoreLifecycleListener implements Application.ActivityLifecycleCallbacks {
|
||||
private boolean _trackAllActivities;
|
||||
private ArrayList<String> _exceptions;
|
||||
private ArrayList<String> _purchaseTypes;
|
||||
|
||||
public StoreLifecycleListener(boolean trackAllActivities, ArrayList<String> exceptions, ArrayList<String> purchaseTypes) {
|
||||
_trackAllActivities = trackAllActivities;
|
||||
_exceptions = exceptions;
|
||||
_purchaseTypes = purchaseTypes;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityStarted(Activity activity) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityResumed(Activity activity) {
|
||||
boolean isException = false;
|
||||
|
||||
if(_exceptions != null) {
|
||||
if(_exceptions.contains(activity.getLocalClassName())) {
|
||||
isException = true;
|
||||
}
|
||||
}
|
||||
|
||||
if((_trackAllActivities && !isException) || (!_trackAllActivities && isException)) {
|
||||
if(_purchaseTypes != null) {
|
||||
StoreMonitor.sendPurchaseStatusOnResume(activity.getLocalClassName(), _purchaseTypes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityPaused(Activity activity) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityStopped(Activity activity) {
|
||||
boolean isException = false;
|
||||
|
||||
if(_exceptions != null) {
|
||||
if(_exceptions.contains(activity.getLocalClassName())) {
|
||||
isException = true;
|
||||
}
|
||||
}
|
||||
|
||||
if((_trackAllActivities && !isException) || (!_trackAllActivities && isException)) {
|
||||
if(_purchaseTypes != null) {
|
||||
StoreMonitor.sendPurchaseStatusOnStop(activity.getLocalClassName(), _purchaseTypes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityDestroyed(Activity activity) {
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,158 @@
|
|||
package com.unity3d.services.store;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.ServiceConnection;
|
||||
import android.os.IBinder;
|
||||
|
||||
import com.unity3d.services.core.properties.ClientProperties;
|
||||
import com.unity3d.services.core.webview.WebViewApp;
|
||||
import com.unity3d.services.core.webview.WebViewEventCategory;
|
||||
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.util.ArrayList;
|
||||
|
||||
@TargetApi(14)
|
||||
public class StoreMonitor {
|
||||
private static Object _billingService;
|
||||
private static StoreLifecycleListener _lifecycleListener;
|
||||
|
||||
public static void initialize(String intentName, String intentPackage) {
|
||||
Intent intent = new Intent(intentName);
|
||||
intent.setPackage(intentPackage);
|
||||
|
||||
ServiceConnection serviceConnection = new ServiceConnection() {
|
||||
@Override
|
||||
public void onServiceConnected(ComponentName name, IBinder service) {
|
||||
_billingService = StoreBilling.asInterface(ClientProperties.getApplicationContext(), service);
|
||||
if(_billingService != null) {
|
||||
WebViewApp.getCurrentApp().sendEvent(WebViewEventCategory.STORE, StoreEvent.INITIALIZED);
|
||||
} else {
|
||||
WebViewApp.getCurrentApp().sendEvent(WebViewEventCategory.STORE, StoreEvent.INITIALIZATION_FAILED);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceDisconnected(ComponentName name) {
|
||||
_billingService = null;
|
||||
|
||||
WebViewApp.getCurrentApp().sendEvent(WebViewEventCategory.STORE, StoreEvent.DISCONNECTED);
|
||||
}
|
||||
};
|
||||
|
||||
ClientProperties.getApplicationContext().bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
|
||||
}
|
||||
|
||||
public static boolean isInitialized() {
|
||||
return _billingService != null;
|
||||
}
|
||||
|
||||
public static int isBillingSupported(String purchaseType) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, StoreException, InvocationTargetException {
|
||||
return StoreBilling.isBillingSupported(ClientProperties.getApplicationContext(), _billingService, purchaseType);
|
||||
}
|
||||
|
||||
public static JSONObject getPurchases(String purchaseType) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, JSONException, IllegalAccessException, StoreException {
|
||||
return StoreBilling.getPurchases(ClientProperties.getApplicationContext(), _billingService, purchaseType);
|
||||
}
|
||||
|
||||
public static JSONObject getPurchaseHistory(String purchaseType, int maxPurchases) throws NoSuchMethodException, StoreException, IllegalAccessException, JSONException, InvocationTargetException, ClassNotFoundException {
|
||||
return StoreBilling.getPurchaseHistory(ClientProperties.getApplicationContext(), _billingService, purchaseType, maxPurchases);
|
||||
}
|
||||
|
||||
public static JSONArray getSkuDetails(String purchaseType, ArrayList<String> skuList) throws NoSuchMethodException, StoreException, IllegalAccessException, JSONException, InvocationTargetException, ClassNotFoundException {
|
||||
return StoreBilling.getSkuDetails(ClientProperties.getApplicationContext(), _billingService, purchaseType, skuList);
|
||||
}
|
||||
|
||||
public static void startPurchaseTracking(boolean trackAllActivities, ArrayList<String> exceptions, ArrayList<String> purchaseTypes) {
|
||||
if(_lifecycleListener != null) {
|
||||
stopPurchaseTracking();
|
||||
}
|
||||
|
||||
_lifecycleListener = new StoreLifecycleListener(trackAllActivities, exceptions, purchaseTypes);
|
||||
ClientProperties.getApplication().registerActivityLifecycleCallbacks(_lifecycleListener);
|
||||
}
|
||||
|
||||
public static void stopPurchaseTracking() {
|
||||
if(_lifecycleListener != null) {
|
||||
ClientProperties.getApplication().unregisterActivityLifecycleCallbacks(_lifecycleListener);
|
||||
_lifecycleListener = null;
|
||||
}
|
||||
}
|
||||
|
||||
public static void sendPurchaseStatusOnResume(String activityName, ArrayList<String> purchaseTypes) {
|
||||
if(!isInitialized()) {
|
||||
WebViewApp.getCurrentApp().sendEvent(WebViewEventCategory.STORE, StoreEvent.PURCHASE_STATUS_ON_RESUME_ERROR, StoreError.NOT_INITIALIZED, activityName, "StoreMonitor not initialized");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
JSONObject results = new JSONObject();
|
||||
|
||||
if(purchaseTypes.contains("inapp")) {
|
||||
JSONObject inAppStatus = getPurchases("inapp");
|
||||
results.put("inapp", inAppStatus);
|
||||
}
|
||||
|
||||
if(purchaseTypes.contains("subs")) {
|
||||
JSONObject subsStatus = getPurchases("subs");
|
||||
results.put("subs", subsStatus);
|
||||
}
|
||||
|
||||
WebViewApp.getCurrentApp().sendEvent(WebViewEventCategory.STORE, StoreEvent.PURCHASE_STATUS_ON_RESUME, activityName, results);
|
||||
} catch (ClassNotFoundException e) {
|
||||
WebViewApp.getCurrentApp().sendEvent(WebViewEventCategory.STORE, StoreEvent.PURCHASE_STATUS_ON_RESUME_ERROR, StoreError.CLASS_NOT_FOUND, activityName, e.getMessage());
|
||||
} catch (NoSuchMethodException e) {
|
||||
WebViewApp.getCurrentApp().sendEvent(WebViewEventCategory.STORE, StoreEvent.PURCHASE_STATUS_ON_RESUME_ERROR, StoreError.NO_SUCH_METHOD, activityName, e.getMessage());
|
||||
} catch (InvocationTargetException e) {
|
||||
WebViewApp.getCurrentApp().sendEvent(WebViewEventCategory.STORE, StoreEvent.PURCHASE_STATUS_ON_RESUME_ERROR, StoreError.INVOCATION_TARGET, activityName, e.getMessage());
|
||||
} catch (JSONException e) {
|
||||
WebViewApp.getCurrentApp().sendEvent(WebViewEventCategory.STORE, StoreEvent.PURCHASE_STATUS_ON_RESUME_ERROR, StoreError.JSON_ERROR, activityName, e.getMessage());
|
||||
} catch (IllegalAccessException e) {
|
||||
WebViewApp.getCurrentApp().sendEvent(WebViewEventCategory.STORE, StoreEvent.PURCHASE_STATUS_ON_RESUME_ERROR, StoreError.ILLEGAL_ACCESS, activityName, e.getMessage());
|
||||
} catch (StoreException e) {
|
||||
WebViewApp.getCurrentApp().sendEvent(WebViewEventCategory.STORE, StoreEvent.PURCHASE_STATUS_ON_RESUME_ERROR, StoreError.STORE_ERROR, activityName, e.getMessage(), e.getResultCode());
|
||||
}
|
||||
}
|
||||
|
||||
public static void sendPurchaseStatusOnStop(String activityName, ArrayList<String> purchaseTypes) {
|
||||
if(!isInitialized()) {
|
||||
WebViewApp.getCurrentApp().sendEvent(WebViewEventCategory.STORE, StoreEvent.PURCHASE_STATUS_ON_STOP_ERROR, StoreError.NOT_INITIALIZED, activityName, "StoreMonitor not initialized");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
JSONObject results = new JSONObject();
|
||||
|
||||
if(purchaseTypes.contains("inapp")) {
|
||||
JSONObject inAppStatus = getPurchases("inapp");
|
||||
results.put("inapp", inAppStatus);
|
||||
}
|
||||
|
||||
if(purchaseTypes.contains("subs")) {
|
||||
JSONObject subsStatus = getPurchases("subs");
|
||||
results.put("subs", subsStatus);
|
||||
}
|
||||
|
||||
WebViewApp.getCurrentApp().sendEvent(WebViewEventCategory.STORE, StoreEvent.PURCHASE_STATUS_ON_STOP, activityName, results);
|
||||
} catch (ClassNotFoundException e) {
|
||||
WebViewApp.getCurrentApp().sendEvent(WebViewEventCategory.STORE, StoreEvent.PURCHASE_STATUS_ON_STOP_ERROR, StoreError.CLASS_NOT_FOUND, activityName, e.getMessage());
|
||||
} catch (NoSuchMethodException e) {
|
||||
WebViewApp.getCurrentApp().sendEvent(WebViewEventCategory.STORE, StoreEvent.PURCHASE_STATUS_ON_STOP_ERROR, StoreError.NO_SUCH_METHOD, activityName, e.getMessage());
|
||||
} catch (InvocationTargetException e) {
|
||||
WebViewApp.getCurrentApp().sendEvent(WebViewEventCategory.STORE, StoreEvent.PURCHASE_STATUS_ON_STOP_ERROR, StoreError.INVOCATION_TARGET, activityName, e.getMessage());
|
||||
} catch (JSONException e) {
|
||||
WebViewApp.getCurrentApp().sendEvent(WebViewEventCategory.STORE, StoreEvent.PURCHASE_STATUS_ON_STOP_ERROR, StoreError.JSON_ERROR, activityName, e.getMessage());
|
||||
} catch (IllegalAccessException e) {
|
||||
WebViewApp.getCurrentApp().sendEvent(WebViewEventCategory.STORE, StoreEvent.PURCHASE_STATUS_ON_STOP_ERROR, StoreError.ILLEGAL_ACCESS, activityName, e.getMessage());
|
||||
} catch (StoreException e) {
|
||||
WebViewApp.getCurrentApp().sendEvent(WebViewEventCategory.STORE, StoreEvent.PURCHASE_STATUS_ON_STOP_ERROR, StoreError.STORE_ERROR, activityName, e.getMessage(), e.getResultCode());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package com.unity3d.services.store.core;
|
||||
|
||||
public class StoreException extends Exception {
|
||||
private int _resultCode;
|
||||
|
||||
public StoreException() {
|
||||
super("Unknown store exception");
|
||||
_resultCode = -1;
|
||||
}
|
||||
|
||||
public StoreException(int resultCode) {
|
||||
super("Store exception with result code " + resultCode);
|
||||
_resultCode = resultCode;
|
||||
}
|
||||
|
||||
public int getResultCode() {
|
||||
return _resultCode;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,206 @@
|
|||
package com.unity3d.services.store.core.api;
|
||||
|
||||
import com.unity3d.services.core.webview.WebViewApp;
|
||||
import com.unity3d.services.core.webview.WebViewEventCategory;
|
||||
import com.unity3d.services.core.webview.bridge.WebViewCallback;
|
||||
import com.unity3d.services.core.webview.bridge.WebViewExposed;
|
||||
import com.unity3d.services.store.StoreError;
|
||||
import com.unity3d.services.store.StoreEvent;
|
||||
import com.unity3d.services.store.StoreMonitor;
|
||||
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.util.ArrayList;
|
||||
|
||||
public class Store {
|
||||
@WebViewExposed
|
||||
public static void initialize(String intentName, String intentPackage, WebViewCallback callback) {
|
||||
try {
|
||||
StoreMonitor.initialize(intentName, intentPackage);
|
||||
callback.invoke();
|
||||
} catch(Exception e) {
|
||||
callback.error(StoreError.UNKNOWN_ERROR, e.getMessage(), e.getClass().getName());
|
||||
}
|
||||
}
|
||||
|
||||
@WebViewExposed
|
||||
public static void startPurchaseTracking(Boolean trackAllActivities, JSONArray exceptions, JSONArray purchaseTypes, WebViewCallback callback) {
|
||||
if(!StoreMonitor.isInitialized()) {
|
||||
callback.error(StoreError.NOT_INITIALIZED);
|
||||
return;
|
||||
}
|
||||
|
||||
ArrayList<String> exceptionList = new ArrayList<>();
|
||||
ArrayList<String> purchaseTypeList = new ArrayList<>();
|
||||
|
||||
try {
|
||||
for (int i = 0; i < exceptions.length(); i++) {
|
||||
exceptionList.add(exceptions.getString(i));
|
||||
}
|
||||
|
||||
for (int i = 0; i < purchaseTypes.length(); i++) {
|
||||
purchaseTypeList.add(purchaseTypes.getString(i));
|
||||
}
|
||||
} catch(JSONException e) {
|
||||
callback.error(StoreError.JSON_ERROR, e.getMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
StoreMonitor.startPurchaseTracking(trackAllActivities, exceptionList, purchaseTypeList);
|
||||
callback.invoke();
|
||||
}
|
||||
|
||||
@WebViewExposed
|
||||
public static void stopPurchaseTracking(WebViewCallback callback) {
|
||||
if(!StoreMonitor.isInitialized()) {
|
||||
callback.error(StoreError.NOT_INITIALIZED);
|
||||
return;
|
||||
}
|
||||
|
||||
StoreMonitor.stopPurchaseTracking();
|
||||
callback.invoke();
|
||||
}
|
||||
|
||||
@WebViewExposed
|
||||
public static void isBillingSupported(final Integer operationId, final String purchaseType, WebViewCallback callback) {
|
||||
if(!StoreMonitor.isInitialized()) {
|
||||
callback.error(StoreError.NOT_INITIALIZED);
|
||||
return;
|
||||
}
|
||||
|
||||
new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
int result = StoreMonitor.isBillingSupported(purchaseType);
|
||||
WebViewApp.getCurrentApp().sendEvent(WebViewEventCategory.STORE, StoreEvent.BILLING_SUPPORTED_RESULT, operationId, result);
|
||||
} catch (InvocationTargetException e) {
|
||||
WebViewApp.getCurrentApp().sendEvent(WebViewEventCategory.STORE, StoreEvent.BILLING_SUPPORTED_ERROR, operationId, StoreError.INVOCATION_TARGET, e.getMessage());
|
||||
} catch (NoSuchMethodException e) {
|
||||
WebViewApp.getCurrentApp().sendEvent(WebViewEventCategory.STORE, StoreEvent.BILLING_SUPPORTED_ERROR, operationId, StoreError.NO_SUCH_METHOD, e.getMessage());
|
||||
} catch (IllegalAccessException e) {
|
||||
WebViewApp.getCurrentApp().sendEvent(WebViewEventCategory.STORE, StoreEvent.BILLING_SUPPORTED_ERROR, operationId, StoreError.ILLEGAL_ACCESS, e.getMessage());
|
||||
} catch (StoreException e) {
|
||||
WebViewApp.getCurrentApp().sendEvent(WebViewEventCategory.STORE, StoreEvent.BILLING_SUPPORTED_ERROR, operationId, StoreError.STORE_ERROR, e.getMessage(), e.getResultCode());
|
||||
} catch (ClassNotFoundException e) {
|
||||
WebViewApp.getCurrentApp().sendEvent(WebViewEventCategory.STORE, StoreEvent.BILLING_SUPPORTED_ERROR, operationId, StoreError.CLASS_NOT_FOUND, e.getMessage());
|
||||
} catch(Exception e) {
|
||||
WebViewApp.getCurrentApp().sendEvent(WebViewEventCategory.STORE, StoreEvent.BILLING_SUPPORTED_ERROR, operationId, StoreError.UNKNOWN_ERROR, e.getMessage(), e.getClass().getName());
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
|
||||
callback.invoke();
|
||||
}
|
||||
|
||||
@WebViewExposed
|
||||
public static void getPurchases(final Integer operationId, final String purchaseType, WebViewCallback callback) {
|
||||
if(!StoreMonitor.isInitialized()) {
|
||||
callback.error(StoreError.NOT_INITIALIZED);
|
||||
return;
|
||||
}
|
||||
|
||||
new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
JSONObject result = StoreMonitor.getPurchases(purchaseType);
|
||||
WebViewApp.getCurrentApp().sendEvent(WebViewEventCategory.STORE, StoreEvent.GETPURCHASES_RESULT, operationId, result);
|
||||
} catch(NoSuchMethodException e) {
|
||||
WebViewApp.getCurrentApp().sendEvent(WebViewEventCategory.STORE, StoreEvent.GETPURCHASES_ERROR, operationId, StoreError.NO_SUCH_METHOD, e.getMessage());
|
||||
} catch(StoreException e) {
|
||||
WebViewApp.getCurrentApp().sendEvent(WebViewEventCategory.STORE, StoreEvent.GETPURCHASES_ERROR, operationId, StoreError.STORE_ERROR, e.getMessage(), e.getResultCode());
|
||||
} catch(IllegalAccessException e) {
|
||||
WebViewApp.getCurrentApp().sendEvent(WebViewEventCategory.STORE, StoreEvent.GETPURCHASES_ERROR, operationId, StoreError.ILLEGAL_ACCESS, e.getMessage());
|
||||
} catch(JSONException e) {
|
||||
WebViewApp.getCurrentApp().sendEvent(WebViewEventCategory.STORE, StoreEvent.GETPURCHASES_ERROR, operationId, StoreError.JSON_ERROR, e.getMessage());
|
||||
} catch(InvocationTargetException e) {
|
||||
WebViewApp.getCurrentApp().sendEvent(WebViewEventCategory.STORE, StoreEvent.GETPURCHASES_ERROR, operationId, StoreError.INVOCATION_TARGET, e.getMessage());
|
||||
} catch(ClassNotFoundException e) {
|
||||
WebViewApp.getCurrentApp().sendEvent(WebViewEventCategory.STORE, StoreEvent.GETPURCHASES_ERROR, operationId, StoreError.CLASS_NOT_FOUND, e.getMessage());
|
||||
} catch(Exception e) {
|
||||
WebViewApp.getCurrentApp().sendEvent(WebViewEventCategory.STORE, StoreEvent.GETPURCHASES_ERROR, operationId, StoreError.UNKNOWN_ERROR, e.getMessage(), e.getClass().getName());
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
|
||||
callback.invoke();
|
||||
}
|
||||
|
||||
@WebViewExposed
|
||||
public static void getPurchaseHistory(final Integer operationId, final String purchaseType, final Integer maxPurchases, WebViewCallback callback) {
|
||||
if(!StoreMonitor.isInitialized()) {
|
||||
callback.error(StoreError.NOT_INITIALIZED);
|
||||
return;
|
||||
}
|
||||
|
||||
new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
JSONObject result = StoreMonitor.getPurchaseHistory(purchaseType, maxPurchases);
|
||||
WebViewApp.getCurrentApp().sendEvent(WebViewEventCategory.STORE, StoreEvent.PURCHASE_HISTORY_RESULT, operationId, result);
|
||||
} catch(NoSuchMethodException e) {
|
||||
WebViewApp.getCurrentApp().sendEvent(WebViewEventCategory.STORE, StoreEvent.PURCHASE_HISTORY_ERROR, operationId, StoreError.NO_SUCH_METHOD, e.getMessage());
|
||||
} catch(StoreException e) {
|
||||
WebViewApp.getCurrentApp().sendEvent(WebViewEventCategory.STORE, StoreEvent.PURCHASE_HISTORY_ERROR, operationId, StoreError.STORE_ERROR, e.getMessage(), e.getResultCode());
|
||||
} catch(IllegalAccessException e) {
|
||||
WebViewApp.getCurrentApp().sendEvent(WebViewEventCategory.STORE, StoreEvent.PURCHASE_HISTORY_ERROR, operationId, StoreError.ILLEGAL_ACCESS, e.getMessage());
|
||||
} catch(JSONException e) {
|
||||
WebViewApp.getCurrentApp().sendEvent(WebViewEventCategory.STORE, StoreEvent.PURCHASE_HISTORY_ERROR, operationId, StoreError.JSON_ERROR, e.getMessage());
|
||||
} catch(InvocationTargetException e) {
|
||||
WebViewApp.getCurrentApp().sendEvent(WebViewEventCategory.STORE, StoreEvent.PURCHASE_HISTORY_ERROR, operationId, StoreError.INVOCATION_TARGET, e.getMessage());
|
||||
} catch(ClassNotFoundException e) {
|
||||
WebViewApp.getCurrentApp().sendEvent(WebViewEventCategory.STORE, StoreEvent.PURCHASE_HISTORY_ERROR, operationId, StoreError.CLASS_NOT_FOUND, e.getMessage());
|
||||
} catch(Exception e) {
|
||||
WebViewApp.getCurrentApp().sendEvent(WebViewEventCategory.STORE, StoreEvent.PURCHASE_HISTORY_ERROR, operationId, StoreError.UNKNOWN_ERROR, e.getMessage(), e.getClass().getName());
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
|
||||
callback.invoke();
|
||||
}
|
||||
|
||||
@WebViewExposed
|
||||
public static void getSkuDetails(final Integer operationId, final String purchaseType, final JSONArray skuList, WebViewCallback callback) {
|
||||
if(!StoreMonitor.isInitialized()) {
|
||||
callback.error(StoreError.NOT_INITIALIZED);
|
||||
return;
|
||||
}
|
||||
|
||||
new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
ArrayList<String> skuArray = new ArrayList<>();
|
||||
for(int i = 0; i < skuList.length(); i++) {
|
||||
skuArray.add(skuList.getString(i));
|
||||
}
|
||||
|
||||
JSONArray result = StoreMonitor.getSkuDetails(purchaseType, skuArray);
|
||||
WebViewApp.getCurrentApp().sendEvent(WebViewEventCategory.STORE, StoreEvent.SKU_DETAILS_RESULT, operationId, result);
|
||||
} catch(JSONException e) {
|
||||
WebViewApp.getCurrentApp().sendEvent(WebViewEventCategory.STORE, StoreEvent.SKU_DETAILS_ERROR, operationId, StoreError.JSON_ERROR, e.getMessage());
|
||||
} catch(NoSuchMethodException e) {
|
||||
WebViewApp.getCurrentApp().sendEvent(WebViewEventCategory.STORE, StoreEvent.SKU_DETAILS_ERROR, operationId, StoreError.NO_SUCH_METHOD, e.getMessage());
|
||||
} catch(IllegalAccessException e) {
|
||||
WebViewApp.getCurrentApp().sendEvent(WebViewEventCategory.STORE, StoreEvent.SKU_DETAILS_ERROR, operationId, StoreError.ILLEGAL_ACCESS, e.getMessage());
|
||||
} catch(StoreException e) {
|
||||
WebViewApp.getCurrentApp().sendEvent(WebViewEventCategory.STORE, StoreEvent.SKU_DETAILS_ERROR, operationId, StoreError.STORE_ERROR, e.getMessage(), e.getResultCode());
|
||||
} catch(ClassNotFoundException e) {
|
||||
WebViewApp.getCurrentApp().sendEvent(WebViewEventCategory.STORE, StoreEvent.SKU_DETAILS_ERROR, operationId, StoreError.CLASS_NOT_FOUND, e.getMessage());
|
||||
} catch(InvocationTargetException e) {
|
||||
WebViewApp.getCurrentApp().sendEvent(WebViewEventCategory.STORE, StoreEvent.SKU_DETAILS_ERROR, operationId, StoreError.INVOCATION_TARGET, e.getMessage());
|
||||
} catch(Exception e) {
|
||||
WebViewApp.getCurrentApp().sendEvent(WebViewEventCategory.STORE, StoreEvent.SKU_DETAILS_ERROR, operationId, StoreError.UNKNOWN_ERROR, e.getMessage(), e.getClass().getName());
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
|
||||
callback.invoke();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
package com.unity3d.services.store.core.configuration;
|
||||
|
||||
import com.unity3d.services.core.configuration.Configuration;
|
||||
import com.unity3d.services.core.configuration.IModuleConfiguration;
|
||||
import com.unity3d.services.store.core.api.Store;
|
||||
|
||||
public class StoreModuleConfiguration implements IModuleConfiguration {
|
||||
private static final Class[] WEB_APP_API_CLASS_LIST = {
|
||||
Store.class,
|
||||
};
|
||||
|
||||
@Override
|
||||
public Class[] getWebAppApiClassList() {
|
||||
return WEB_APP_API_CLASS_LIST;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean resetState(Configuration configuration) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean initModuleState(Configuration configuration) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean initErrorState(Configuration configuration, String state, String message) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean initCompleteState(Configuration configuration) {
|
||||
return true;
|
||||
}
|
||||
}
|
Загрузка…
Ссылка в новой задаче