public bool CloseView(bool saveViewState) { return(JniUtils.RunOnUiThreadSafe(() => { _getUiSocialJavaClass.CallStatic("closeView", saveViewState); })); }
public bool RestoreView() { return(JniUtils.RunOnUiThreadSafe(() => { _getUiSocialJavaClass.CallStatic("restoreView"); })); }
public bool LoadConfiguration(string path) { return(JniUtils.RunOnUiThreadSafe(() => { _getUiSocialJavaClass.CallStaticBool("loadConfiguration", JniUtils.Activity, path); })); }
public bool LoadDefaultConfiguration() { return(JniUtils.RunOnUiThreadSafe(() => { _getUiSocialJavaClass.CallStaticBool("loadDefaultConfiguration", JniUtils.Activity); })); }
void InstantiateBillingClientAndMakeConnection() { _billingClientStateListener = new BillingClientStateListener(); _billingClientStateListener.OnBillingServiceDisconnected += () => { Debug.Log("Service disconnected"); EndConnection(); //InstantiateBillingClientAndMakeConnection(); }; _billingClientStateListener.OnBillingSetupFinished += (billingResult) => MarkBillingClientStartConnectionCallComplete(billingResult); // Set ready flag to false as this action could be triggered when in-app billing service is disconnected. _billingClientReady = false; var context = JniUtils.GetApplicationContext(); _billingClient = new AndroidJavaObject("com.android.billingclient.api.BillingClientImpl", "3.0.0-unity"); _billingClient.Call( "initialize", context, null, _deferredPurchasesEnabled); _billingClient.Call("startConnection", _billingClientStateListener); }
private void ProcessPriceChangeResult(AndroidJavaObject billingResult, Action <bool> callback) { var responseCode = _jniUtils.GetResponseCodeFromBillingResult(billingResult); if (responseCode != BillingResponseCode.Ok) { _billingUtil.LogWarningFormat( "Confirming subscription price change failed with error code {0} and debug message: {1}", responseCode, JniUtils.GetDebugMessageFromBillingResult(billingResult)); } callback.Invoke(responseCode == BillingResponseCode.Ok); }
private void MarkBillingClientStartConnectionCallComplete(AndroidJavaObject billingResult) { var responseCode = _jniUtils.GetResponseCodeFromBillingResult(billingResult); if (responseCode == BillingResponseCode.Ok) { _billingClientReady = true; } else { _billingUtil.LogErrorFormat( "Failed to connect to service with error code '{0}' and debug message: '{1}'.", responseCode, JniUtils.GetDebugMessageFromBillingResult(billingResult)); } }
protected bool ShowBuilder(AndroidJavaObject builder) { SetUiActionListenerAJO(builder); SetTitleAJO(builder); SetViewStateListener(builder); // Make sure ui is instantiated at this point for ensuring OnResume was called before opening the view GetSocialUiFactory.InstantiateGetSocialUi(); return(JniUtils.RunOnUiThreadSafe(() => { using (builder) { builder.CallBool("show"); } })); }
private void ProcessConsumePurchaseResult(string skuId, AndroidJavaObject billingResult) { var responseCode = _jniUtils.GetResponseCodeFromBillingResult(billingResult); if (responseCode == BillingResponseCode.Ok) { _inventory.RemovePurchase(skuId); } else { var debugMessage = JniUtils.GetDebugMessageFromBillingResult(billingResult); _billingUtil.LogErrorFormat( "Failed to finish the transaction with error code {0} and debug message: {1}. " + "Please consider to call FinishAdditionalTransaction using the extension.", responseCode, debugMessage); } }
// Launches billing flow using billingFlowParamBuilder, in addition, it will add corresponding // accountId, developerId parameters. private void LaunchBillingFlow(AndroidJavaObject billingFlowParamBuilder) { if (!string.IsNullOrEmpty(_obfuscatedProfileId)) { billingFlowParamBuilder.Call <AndroidJavaObject>( Constants.BillingFlowParamsBuilderSetObfuscatedProfileIdMethod, _obfuscatedProfileId); } if (!string.IsNullOrEmpty(_obfuscatedAccountId)) { billingFlowParamBuilder.Call <AndroidJavaObject>( Constants.BillingFlowParamsBuilderSetObfuscatedAccountIdMethod, _obfuscatedAccountId); } _billingClient.Call <AndroidJavaObject>( Constants.BillingClientLaunchBillingFlowMethod, JniUtils.GetUnityAndroidActivity(), billingFlowParamBuilder.Call <AndroidJavaObject>(Constants.BuildMethod)); }
private void ProcessAcknowledgePurchaseResult(string skuId, SkuType skuType, AndroidJavaObject billingResult) { string productId; if (!_inventory.GetUnityProductId(skuId, out productId)) { _billingUtil.LogErrorFormat( "Couldn't find Unity product that maps to {0} when processing acknowledge purchase result", skuId); return; } var responseCode = _jniUtils.GetResponseCodeFromBillingResult(billingResult); if (responseCode != BillingResponseCode.Ok) { _billingUtil.LogErrorFormat( "Acknowledging purchase {0} failed with error code {1} and debug message: {2}.", productId, _jniUtils.GetResponseCodeFromBillingResult(billingResult), JniUtils.GetDebugMessageFromBillingResult(billingResult)); return; } // Call queryPurchases again to update the acknowledge status. var queryResult = QueryPurchasesForSkuType(skuType); if (queryResult != BillingResponseCode.Ok) { _billingUtil.LogWarningFormat( "Update the purchase {0} after FinishTransaction failed with error code {1}. " + "The purchase receipt might be out of date. One can call FetchAdditionalProducts " + "on this product to get the updated purchase receipt.", productId, queryResult); } // Double check updated results.... var updateList = _inventory.UpdateProductDescriptionList(new List <string> { skuId }); _callback.OnProductsRetrieved(updateList); }
private void QuerySkuDetailsForSkuType(ReadOnlyCollection <ProductDefinition> products, SkuType skuType) { var skuDetailsParamBuilder = new AndroidJavaObject(Constants.SkuDetailsParamBuilder); string[] skuIds = { }; if (skuType == SkuType.InApp) { skuIds = products.Where(p => p.type == ProductType.Consumable || p.type == ProductType.NonConsumable) .Select(p => p.storeSpecificId).ToArray(); } else if (skuType == SkuType.Subs) { skuIds = products.Where(p => p.type == ProductType.Subscription).Select(p => p.storeSpecificId) .ToArray(); } else { throw new NotImplementedException(String.Format("Unsupported Google Play Store skuType {0}.", skuType)); } // Set the SkuDetails request status to success state if the list is empty. if (!skuIds.Any()) { _billingClientQuerySkuDetailsCallStatus[skuType] = AsyncRequestStatus.Succeed; NotifyUnityRetrieveProductsResults(); return; } skuDetailsParamBuilder.Call <AndroidJavaObject>(Constants.SkuDetailsParamBuilderSetSkuListMethod, JniUtils.CreateJavaArrayList(skuIds)); skuDetailsParamBuilder.Call <AndroidJavaObject>(Constants.SkuDetailsParamBuilderSetTypeMethod, skuType.ToString()); var skuDetailsParam = skuDetailsParamBuilder.Call <AndroidJavaObject>(Constants.BuildMethod); var skuDetailsResponseListener = new SkuDetailsResponseListener(skuType); skuDetailsResponseListener.OnSkuDetailsResponse += ParseSkuDetailsResults; _billingClient.Call(Constants.QuerySkuDetailsMethod, skuDetailsParam, skuDetailsResponseListener); }
private void InstantiateBillingClientAndMakeConnection() { // Set ready flag to false as this action could be triggered when in-app billing service is disconnected. _billingClientReady = false; var context = JniUtils.GetApplicationContext(); _billingClient = new AndroidJavaObject(Constants.BillingClient, Constants.Version); var purchaseUpdatedListener = new PurchasesUpdatedListener(); purchaseUpdatedListener.OnPurchasesUpdated += ParsePurchaseResult; _billingClient.Call( Constants.BillingClientSetUpMethod, context, purchaseUpdatedListener, _deferredPurchasesEnabled); _billingClient.Call(Constants.BillingClientStartConnectionMethod, _billingClientStateListener); }
public void ConfirmSubscriptionPriceChange(string productId, Action <bool> callback) { if (!IsGooglePlayInAppBillingServiceAvailable()) { _billingUtil.RunOnMainThread(() => callback.Invoke(false)); return; } ProductDefinition unityProduct; SkuDetails skuDetails; if (!_inventory.GetUnityProductDefinition(productId, out unityProduct) || !_inventory.GetSkuDetails(unityProduct.storeSpecificId, out skuDetails)) { _billingUtil.LogErrorFormat("Cannot find SKU for Unity product {0}", productId); _billingUtil.RunOnMainThread(() => callback.Invoke(false)); return; } var listener = new PriceChangeConfirmationListener(); Action <AndroidJavaObject> cb = (billingResult) => _billingUtil.RunOnMainThread(() => ProcessPriceChangeResult(billingResult, callback)); listener.OnPriceChangeConfirmationResult += cb; using (var priceChangeConfirmationParamBuilder = new AndroidJavaObject(Constants.PriceChangeFlowParamsBuilder) .Call <AndroidJavaObject>(Constants.PriceChangeFlowParamsBuilderSetSkuDetailsMethod, skuDetails.ToJava())) { _billingClient.Call( Constants.LaunchPriceChangeConfirmationFlowMethod, JniUtils.GetUnityAndroidActivity(), priceChangeConfirmationParamBuilder.Call <AndroidJavaObject>(Constants.BuildMethod), listener); } }
public static void LogError(string message) { JniUtils.CallStatic(LogErrorMethod, message, LoggerPluginClass); }
public GooglePlayStoreImpl(GooglePlayBillingUtil googlePlayBillingUtil) { _inventory = new GooglePlayBillingInventory(); _billingUtil = googlePlayBillingUtil; _jniUtils = new JniUtils(_billingUtil); }
private void ParsePurchaseResult(AndroidJavaObject billingResult, AndroidJavaObject javaPurchasesList) { var responseCode = _jniUtils.GetResponseCodeFromBillingResult(billingResult); var debugMessage = JniUtils.GetDebugMessageFromBillingResult(billingResult); if (responseCode == BillingResponseCode.Ok) { var purchasesList = _jniUtils.ParseJavaPurchaseList(javaPurchasesList); _inventory.UpdatePurchaseInventory(purchasesList); // Unity IAP only supports one purchase at a time. Purchase purchase = purchasesList.First(); if (Google.Play.Billing.Internal.Purchase.State.Pending.Equals(purchase.PurchaseState)) { string unityProductId; _inventory.GetUnityProductId(purchase.ProductId, out unityProductId); _billingUtil.RunOnMainThread(() => _deferredPurchaseListener.Invoke(_callback.products.WithID(unityProductId))); } else { _billingUtil.RunOnMainThread(() => _callback.OnPurchaseSucceeded(purchase.ProductId, purchase.JsonReceipt, purchase.TransactionId)); } } else { _billingUtil.LogWarningFormat("Purchase failed with error code '{0}' and debug message: '{1}'", responseCode, debugMessage); PurchaseFailureReason purchaseFailureReason; switch (responseCode) { case BillingResponseCode.UserCancelled: purchaseFailureReason = PurchaseFailureReason.UserCancelled; break; case BillingResponseCode.ServiceTimeout: case BillingResponseCode.ServiceDisconnected: case BillingResponseCode.ServiceUnavailable: case BillingResponseCode.BillingUnavailable: purchaseFailureReason = PurchaseFailureReason.PurchasingUnavailable; break; case BillingResponseCode.ItemUnavailable: purchaseFailureReason = PurchaseFailureReason.ProductUnavailable; break; case BillingResponseCode.ItemAlreadyOwned: purchaseFailureReason = PurchaseFailureReason.DuplicateTransaction; break; default: purchaseFailureReason = PurchaseFailureReason.Unknown; break; } // Copy _productInPurchaseFlow.id into the delegate as the delegate is called by the main thread and // _productInPurchaseFlow will get cleaned up immediately in this thread. var productId = _productInPurchaseFlow.id; _billingUtil.RunOnMainThread(() => _callback.OnPurchaseFailed( new PurchaseFailureDescription(productId, purchaseFailureReason, debugMessage))); } _productInPurchaseFlow = null; }
public static void ShowToast(string message, ToastLength toastLength = ToastLength.Short) { JniUtils.CallWithUnityActivity(ShowToastMethod, message, (int)toastLength, ToastPluginClass); }
void MarkBillingClientStartConnectionCallComplete(AndroidJavaObject billingResult) { var responseCode = this.GetResponseCodeFromBillingResult(billingResult); if (responseCode == BillingResponseCode.Ok) { _billingClientReady = true; } else { Debug.Log( $"Failed to connect to service with error code '{responseCode}' and debug message: '{JniUtils.GetDebugMessageFromBillingResult(billingResult)}'."); } }