+ * This load item list by starting productActivity in this library, and the result will be sent to {@link OnGetProductsDetailsListener} Callback + * interface. + * + *+ * + * @param _productIds + * @param _onGetProductsDetailsListener + */ + public void getProductsDetails + ( + String _productIds, + OnGetProductsDetailsListener _onGetProductsDetailsListener + ) { + try { + if (_onGetProductsDetailsListener == null) { + throw new Exception("_onGetProductsDetailsListener is null"); + } + + ProductsDetails productsDetails = new ProductsDetails(mInstance, mContext, _onGetProductsDetailsListener); + productsDetails.setProductId(_productIds); + setServiceProcess(productsDetails); + + IapStartInProgressFlag(); + checkAppsPackage(); + } catch (IapInProgressException e) { + e.printStackTrace(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * execute GetProductsDetailsTask + */ + public boolean safeGetProductsDetails + ( + ProductsDetails _baseService, + String _productIDs, + boolean _showErrorDialog + ) { + try { + if (mGetProductsDetailsTask != null && + mGetProductsDetailsTask.getStatus() != Status.FINISHED) { + mGetProductsDetailsTask.cancel(true); + } + if (mIapConnector == null || mContext == null) { + return false; + } else { + mGetProductsDetailsTask = new GetProductsDetailsTask(_baseService, + mIapConnector, + mContext, + _productIDs, + _showErrorDialog, + mMode); + mGetProductsDetailsTask.execute(); + return true; + } + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + + /////////////////////////////////////////////////////////////////////////// + // 3.2) getOwnedList ////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////// + + /** + *
+ * This load owned product list by starting OwnedListActivity in this library, and the result will be sent to {@link OnGetOwnedListListener} + * Callback interface. + * + *+ * + * @param _productType + * @param _onGetOwnedListListener + */ + public boolean getOwnedList + ( + String _productType, + OnGetOwnedListListener _onGetOwnedListListener + ) { + Log.i(TAG, "getOwnedList"); + try { + if (_onGetOwnedListListener == null) { + throw new Exception("_onGetOwnedListListener is null"); + } + if (TextUtils.isEmpty(_productType)) { + throw new Exception("_productType is null or empty"); + } + + OwnedProduct ownedProduct = new OwnedProduct(mInstance, mContext, _onGetOwnedListListener); + ownedProduct.setProductType(_productType); + setServiceProcess(ownedProduct); + + IapStartInProgressFlag(); + checkAppsPackage(); + } catch (IapInProgressException e) { + e.printStackTrace(); + } catch (Exception e) { + e.printStackTrace(); + return false; + } + return true; + } + + /** + * execute GetOwnedListTask + */ + public boolean safeGetOwnedList + ( + OwnedProduct _baseService, + String _productType, + boolean _showErrorDialog + ) { + try { + if (mGetOwnedListTask != null && + mGetOwnedListTask.getStatus() != Status.FINISHED) { + mGetOwnedListTask.cancel(true); + } + + if (mIapConnector == null || mContext == null) { + return false; + } else { + mGetOwnedListTask = new GetOwnedListTask(_baseService, + mIapConnector, + mContext, + _productType, + _showErrorDialog, + mMode); + + mGetOwnedListTask.execute(); + return true; + } + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /////////////////////////////////////////////////////////////////////////// + // 3.3) consumePurchasedItems ///////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////// + + /** + *
+ * This load item list by starting OwnedListActivity in this library, and the result will be sent to {@link OnConsumePurchasedItemsListener} + * Callback interface. + * + *+ * + * @param _purchaseIds + * @param _onConsumePurchasedItemsListener + */ + public boolean consumePurchasedItems + ( + String _purchaseIds, + OnConsumePurchasedItemsListener _onConsumePurchasedItemsListener + ) { + try { + if (_onConsumePurchasedItemsListener == null) { + throw new Exception("_onConsumePurchasedItemsListener is null"); + } + if (TextUtils.isEmpty(_purchaseIds)) { + throw new Exception("_purchaseIds is null or empty"); + } + + ConsumePurchasedItems consumePurchasedItems = new ConsumePurchasedItems(mInstance, mContext, _onConsumePurchasedItemsListener); + consumePurchasedItems.setPurchaseIds(_purchaseIds); + setServiceProcess(consumePurchasedItems); + + IapStartInProgressFlag(); + checkAppsPackage(); + } catch (IapInProgressException e) { + e.printStackTrace(); + } catch (Exception e) { + e.printStackTrace(); + return false; + } + return true; + } + + /** + * execute ConsumePurchasedItemsTask + */ + public boolean safeConsumePurchasedItems + ( + ConsumePurchasedItems _baseService, + String _purchaseIds, + boolean _showErrorDialog + ) { + try { + if (mConsumePurchasedItemsTask != null && + mConsumePurchasedItemsTask.getStatus() != Status.FINISHED) { + mConsumePurchasedItemsTask.cancel(true); + } + + mConsumePurchasedItemsTask = new ConsumePurchasedItemsTask(_baseService, + mIapConnector, + mContext, + _purchaseIds, + _showErrorDialog, + mMode); + mConsumePurchasedItemsTask.execute(); + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /////////////////////////////////////////////////////////////////////////// + // 3.4) startPurchase / /////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////// + + /** + *
+ * Start payment process by starting {@link PaymentActivity} in this library, and result will be sent to {@link OnPaymentListener} interface. To + * do that, PaymentActivity must be described in AndroidManifest.xml of third-party application as below. + *+ * + * @param _itemId + * @param _passThroughParam + * @param _onPaymentListener + */ + public boolean startPayment + ( + String _itemId, + String _passThroughParam, + OnPaymentListener _onPaymentListener + ) { + try { + if (_onPaymentListener == null) { + throw new Exception("OnPaymentListener is null"); + } + if (TextUtils.isEmpty(_itemId)) { + throw new Exception("_itemId is null or empty"); + } + if (_passThroughParam != null && _passThroughParam.getBytes("UTF-8").length > HelperDefine.PASSTHROGUH_MAX_LENGTH) { + throw new Exception("PassThroughParam length exceeded (MAX " + HelperDefine.PASSTHROGUH_MAX_LENGTH + ")"); + } + + IapStartInProgressFlag(); + mListenerInstance.setOnPaymentListener(_onPaymentListener); + + Intent intent = new Intent(mContext, PaymentActivity.class); + intent.putExtra("ItemId", _itemId); + String encodedPassThroughParam = ""; + if (_passThroughParam != null) { + encodedPassThroughParam = Base64.encodeToString(_passThroughParam.getBytes("UTF-8"), 0); + } + intent.putExtra("PassThroughParam", encodedPassThroughParam); + intent.putExtra("ShowErrorDialog", mShowErrorDialog); + intent.putExtra("OperationMode", mMode); + Log.i(TAG, "startPayment: " + mMode); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + + mContext.startActivity(intent); + } catch (IapInProgressException e) { + e.printStackTrace(); + return false; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + return true; + } + + /** + *+ * <activity android:name="com.sec.android.iap.lib.activity.PaymentActivity" android:theme="@style/Theme.Empty" + * android:configChanges="orientation|screenSize"/> + *
+ * Start payment process by starting {@link PaymentActivity} in this library, and result will be sent to {@link OnPaymentListener} interface. To + * do that, PaymentActivity must be described in AndroidManifest.xml of third-party application as below. + *+ * + * @param _itemId + * @param _passThroughParam + * @param _showSuccessDialog Unused parameter. + * @param _onPaymentListener + * @deprecated + */ + public boolean startPayment + ( + String _itemId, + String _passThroughParam, + boolean _showSuccessDialog, + OnPaymentListener _onPaymentListener + ) { + return startPayment(_itemId, _passThroughParam, _onPaymentListener); + } + + // ######################################################################## + // ######################################################################## + // 4. etc + // ######################################################################## + // ######################################################################## + + /** + * Stop running task, {@link GetProductsDetailsTask}, {@link ConsumePurchasedItemsTask} or {@link GetOwnedListTask} } before dispose(). + */ + private void stopTasksIfNotFinished() { + if (mGetProductsDetailsTask != null) { + if (mGetProductsDetailsTask.getStatus() != Status.FINISHED) { + Log.e(TAG, "stopTasksIfNotFinished: mGetProductsDetailsTask Status > " + mGetProductsDetailsTask.getStatus()); + mGetProductsDetailsTask.cancel(true); + } + } + + if (mGetOwnedListTask != null) { + if (mGetOwnedListTask.getStatus() != Status.FINISHED) { + Log.e(TAG, "stopTasksIfNotFinished: mGetOwnedListTask Status > " + mGetOwnedListTask.getStatus()); + mGetOwnedListTask.cancel(true); + } + } + + if (mConsumePurchasedItemsTask != null) { + if (mConsumePurchasedItemsTask.getStatus() != Status.FINISHED) { + Log.e(TAG, "stopTasksIfNotFinished: mConsumePurchasedItemsTask Status > " + mConsumePurchasedItemsTask.getStatus()); + mConsumePurchasedItemsTask.cancel(true); + } + } + } + + /** + * Unbind from IAPService and release used resources. + */ + public void dispose() { + stopTasksIfNotFinished(); + + if (mContext != null && mServiceConn != null) { + mContext.unbindService(mServiceConn); + } + + mState = HelperDefine.STATE_TERM; + mServiceConn = null; + mIapConnector = null; + clearServiceProcess(); + IapEndInProgressFlag(); + } + + void IapStartInProgressFlag() throws IapInProgressException { + Log.i(TAG, "IapStartInProgressFlag"); + synchronized (mOperationLock) { + if (mOperationRunningFlag) { + throw new IapInProgressException("another operation is running"); + } + mOperationRunningFlag = true; + } + } + + void IapEndInProgressFlag() { + Log.i(TAG, "IapEndInProgressFlag"); + synchronized (mOperationLock) { + mOperationRunningFlag = false; + } + } + + protected static class IapInProgressException extends Exception { + public IapInProgressException(String message) { + super(message); + } + } + + void checkAppsPackage() { + int checkResult = HelperUtil.checkAppsPackage(mContext); + if (checkResult == HelperDefine.DIALOG_TYPE_NONE) { + bindIapService(); + } else { + Intent intent = new Intent(mContext, CheckPackageActivity.class); + intent.putExtra("DialogType", checkResult); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + mContext.startActivity(intent); + } + } + + /** + * Sets whether error popup is displayed when payment is finished. + */ + public void setShowErrorDialog(boolean _showErrorDialog) { + this.mShowErrorDialog = _showErrorDialog; + } + + public boolean getShowErrorDialog() { + return this.mShowErrorDialog; + } + + public BaseService getServiceProcess() { + return getServiceProcess(false); + } + + public BaseService getServiceProcess(boolean _nextProcess) { + if (mCurrentService == null || _nextProcess) { + mCurrentService = null; + if (mServiceQueue.size() > 0) { + mCurrentService = mServiceQueue.get(0); + mServiceQueue.remove(0); + } + } + return mCurrentService; + } + + private void setServiceProcess(BaseService _baseService) { + mServiceQueue.add(_baseService); + } + + private void clearServiceProcess() { + do { + if (mCurrentService != null) { + mCurrentService.releaseProcess(); + } + mCurrentService = getServiceProcess(true); + } while (mCurrentService != null); + mServiceQueue.clear(); + } +} \ No newline at end of file diff --git a/IAP6Helper/src/main/java/com/samsung/android/sdk/iap/lib/helper/task/BaseTask.java b/IAP6Helper/src/main/java/com/samsung/android/sdk/iap/lib/helper/task/BaseTask.java new file mode 100644 index 000000000..c284cef37 --- /dev/null +++ b/IAP6Helper/src/main/java/com/samsung/android/sdk/iap/lib/helper/task/BaseTask.java @@ -0,0 +1,65 @@ +package com.samsung.android.sdk.iap.lib.helper.task; + +import android.content.Context; +import android.os.AsyncTask; +import android.util.Log; + +import com.samsung.android.iap.IAPConnector; +import com.samsung.android.sdk.iap.lib.R; +import com.samsung.android.sdk.iap.lib.helper.HelperDefine; +import com.samsung.android.sdk.iap.lib.service.BaseService; +import com.samsung.android.sdk.iap.lib.vo.ErrorVo; + +/** + * Created by sangbum7.kim on 2017-09-01. + */ + +public class BaseTask extends AsyncTask+ * <activity android:name="com.sec.android.iap.lib.activity.PaymentActivity" android:theme="@style/Theme.Empty" + * android:configChanges="orientation|screenSize"/> + *
oxsuL0=pw
z;r9H>lM`ESPEW!_Z!W`a#CR4S4$u3GaE(0xCpzqhEA10^3(ct0c>XMy9&P}zEua+#
zG`X52I#zQ* o`bHM$hB{9RylCUuF>TUPd~Z(_Tf(2
zHCNtk1{q@|Hi%E_r|&kYP*E9?jRbM0^-QmyJb7*EDk>^&ligaKogO#Y$C75Cb8~ZG
z!@80lo5Wb(r^UlJ_A*kq9|b4PQ&*N8h%<5Xik@(8{i5xzRdn~9ZkU?c@bW1WmjMBU
zO!zInplPWkpwP*Z@ID2I?Nd@~bk@_Q-gp(M_yn
$?EhSFeL+)sjw(d~oq*6vSttXmcfdMPiOTtFMO9wWYJ&N3W
zscG)P(!r_~O)&8dKWxs{0pX=xGcgTHa8?`GdA-YS!!mWpYHOJKAlxl|*^&uv(BgQw
z-eMT6ba%{CN2u4OW<+Y@+*RE6A_s&sNyuo$Q^+&HV_5puDI|?%-)bf@sZ1581$=*)
z-5#*KdGR@
q0N1C~iCfhw;(leJe^!SDl#RCGYCVdvMsvfu>EQ$k_r@#b
z2x=0%0j@0cw{`kP=#vuI&}_^s{GHUQZ4${W?-(DECNM~O5RwoYJPxm(F6Q}^Rq#9h
zA>dWhJ9dZZH_CcJ;F+{2-{?R>Hy8|XFJ|g8WYURpR4!x(mj{oVYvGvoJBRm3NmI|z
z7=Z?029BC6Cp}9uk1{_?^DlL}10a?MDouek8wNNE)s#@DI+BlCQvjs_@j)#P2ImtF
zy^y|X4ioge7`$Vdjk#UwkayP#rx$0drd3kHk>=o^bzREEW1}soAeCdTPexHG^kGm}
zD6Cz{MfW|Y;#q)+0=;N|%T!-IK>V2RP`ibrVf_