diff --git a/res/raw/linphonerc_factory b/res/raw/linphonerc_factory index 3a1c800cb..5aec262ee 100644 --- a/res/raw/linphonerc_factory +++ b/res/raw/linphonerc_factory @@ -33,4 +33,4 @@ log_collection_upload_server_url=https://www.linphone.org:444/lft.php user_certificates_path=/data/data/org.linphone/files [in-app-purchase] -server_url=https://www.linphone.org/wizard2.php \ No newline at end of file +server_url=https://www.linphone.org/inapp.php \ No newline at end of file diff --git a/src/org/linphone/purchase/InAppPurchaseActivity.java b/src/org/linphone/purchase/InAppPurchaseActivity.java index 28c323711..8df20f486 100644 --- a/src/org/linphone/purchase/InAppPurchaseActivity.java +++ b/src/org/linphone/purchase/InAppPurchaseActivity.java @@ -32,14 +32,14 @@ import android.view.View.OnClickListener; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; -import android.widget.Toast; /** * @author Sylvain Berfini */ public class InAppPurchaseActivity extends Activity implements InAppPurchaseListener, OnClickListener { private InAppPurchaseHelper inAppPurchaseHelper; - private LinearLayout purchasableItems; + private LinearLayout purchasableItemsLayout; + private ArrayList purchasedItems; @Override protected void onCreate(Bundle savedInstanceState) { @@ -48,7 +48,7 @@ public class InAppPurchaseActivity extends Activity implements InAppPurchaseList inAppPurchaseHelper = new InAppPurchaseHelper(this, this); setContentView(R.layout.in_app_store); - purchasableItems = (LinearLayout) findViewById(R.id.purchasable_items); + purchasableItemsLayout = (LinearLayout) findViewById(R.id.purchasable_items); } @Override @@ -59,29 +59,35 @@ public class InAppPurchaseActivity extends Activity implements InAppPurchaseList @Override public void onServiceAvailableForQueries() { - inAppPurchaseHelper.getAvailableItemsForPurchaseAsync(); inAppPurchaseHelper.getPurchasedItemsAsync(); } @Override public void onAvailableItemsForPurchaseQueryFinished(ArrayList items) { - purchasableItems.removeAllViews(); + purchasableItemsLayout.removeAllViews(); for (Purchasable item : items) { - View layout = LayoutInflater.from(this).inflate(R.layout.in_app_purchasable, purchasableItems); + View layout = LayoutInflater.from(this).inflate(R.layout.in_app_purchasable, purchasableItemsLayout); TextView text = (TextView) layout.findViewById(R.id.text); - text.setText(item.getTitle() + " (" + item.getPrice() + ")"); + text.setText(item.getTitle() + " " + item.getPrice()); ImageView image = (ImageView) layout.findViewById(R.id.image); image.setTag(item); image.setOnClickListener(this); + + for (Purchasable purchasedItem : purchasedItems) { + Log.d("[In-app purchase] Found already bought item"); + if (purchasedItem.getId().equals(item.getId())) { + image.setEnabled(false); + text.setEnabled(false); + } + } } } @Override public void onPurchasedItemsQueryFinished(ArrayList items) { - for (Purchasable item : items) { - Log.d("[In-app] Item " + item.getTitle() + " is already bought"); - } + purchasedItems = items; + inAppPurchaseHelper.getAvailableItemsForPurchaseAsync(); } @Override diff --git a/src/org/linphone/purchase/InAppPurchaseHelper.java b/src/org/linphone/purchase/InAppPurchaseHelper.java index 289a6977d..0f66b3cf1 100644 --- a/src/org/linphone/purchase/InAppPurchaseHelper.java +++ b/src/org/linphone/purchase/InAppPurchaseHelper.java @@ -245,12 +245,10 @@ public class InAppPurchaseHelper { String signature = signatureList.get(i); Log.d("[In-app purchase] Found purchase data: " + purchaseData); - verifySignatureAsync(new VerifiedSignatureListener() { - @Override - public void onParsedAndVerifiedSignatureQueryFinished(Purchasable item) { - items.add(item); - } - }, purchaseData, signature); + Purchasable item = verifySignature(purchaseData, signature); + if (item != null) { + items.add(item); + } } } else { Log.e("[In-app purchase] Error: responde code is not ok: " + responseCodeToErrorMessage(response)); @@ -303,7 +301,7 @@ public class InAppPurchaseHelper { if (resultCode == Activity.RESULT_OK && responseCode == RESPONSE_RESULT_OK) { Log.d("[In-app purchase] response is OK"); - verifySignatureAsync(new VerifiedSignatureListener() { + verifySignatureAndCreateAccountAsync(new VerifiedSignatureListener() { @Override public void onParsedAndVerifiedSignatureQueryFinished(Purchasable item) { mListener.onPurchasedItemConfirmationQueryFinished(item); @@ -319,7 +317,7 @@ public class InAppPurchaseHelper { mContext.unbindService(mServiceConn); } - private void verifySignatureAsync(final VerifiedSignatureListener listener, String purchasedData, String signature) { + private Purchasable verifySignature(String purchasedData, String signature) { XMLRPCClient client = null; try { client = new XMLRPCClient(new URL(LinphonePreferences.instance().getInAppPurchaseValidatingServerUrl())); @@ -327,30 +325,66 @@ public class InAppPurchaseHelper { Log.e(e); } + if (client != null) { + try { + Object result = client.call("check_signature", purchasedData, signature, "google"); + String object = (String)result; + JSONObject json = new JSONObject(object); + Log.d("[In-app purchase] JSON received is " + json); + String productId = json.getString(PURCHASE_DETAILS_PRODUCT_ID); + Log.d("[In-app purchase] Purchasable verified by server: " + productId); + Purchasable item = new Purchasable(productId); + //TODO parse JSON result to get the purchasable in it + return item; + } catch (XMLRPCException e) { + Log.e(e); + } catch (JSONException e) { + Log.e(e); + } + } + + return null; + } + + private void verifySignatureAndCreateAccountAsync(final VerifiedSignatureListener listener, String purchasedData, String signature) { + XMLRPCClient client = null; + try { + client = new XMLRPCClient(new URL(LinphonePreferences.instance().getInAppPurchaseValidatingServerUrl())); + } catch (MalformedURLException e) { + Log.e(e); + Log.e("[In-app purchase] Can't reach the server !"); + } + if (client != null) { client.callAsync(new XMLRPCCallback() { @Override public void onServerError(long id, XMLRPCServerException error) { Log.e(error); + Log.e("[In-app purchase] Server can't validate the payload and it's signature !"); } @Override public void onResponse(long id, Object result) { try { - JSONObject object = new JSONObject((String)result); - String productId = object.getString(PURCHASE_DETAILS_PRODUCT_ID); + String object = (String)result; + JSONObject json = new JSONObject(object); + Log.d("[In-app purchase] JSON received is " + json); + String productId = json.getString(PURCHASE_DETAILS_PRODUCT_ID); Log.d("[In-app purchase] Purchasable verified by server: " + productId); Purchasable item = new Purchasable(productId); //TODO parse JSON result to get the purchasable in it listener.onParsedAndVerifiedSignatureQueryFinished(item); + return; } catch (JSONException e) { Log.e(e); } + Log.e("[In-app purchase] Server can't validate the payload and it's signature !"); } @Override public void onError(long id, XMLRPCException error) { Log.e(error); + Log.e("[In-app purchase] Server can't validate the payload and it's signature !"); } }, "create_account_from_in_app_purchase", "sylvain@sip.linphone.org", "toto", purchasedData, signature, "google"); }