37
37
import android .app .PendingIntent .CanceledException ;
38
38
import android .content .Context ;
39
39
import android .content .Intent ;
40
+ import android .os .AsyncTask ;
40
41
import android .text .TextUtils ;
41
42
import android .util .Log ;
42
43
@@ -60,9 +61,12 @@ public interface IConfiguration {
60
61
61
62
/**
62
63
* Returns the public key used to verify the signature of responses of
63
- * the Market Billing service.
64
+ * the Google Play Billing service. If you are using a custom signature
65
+ * validator with server-side validation this method might not be needed
66
+ * and can return null.
64
67
*
65
68
* @return Base64 encoded public key.
69
+ * @see BillingController#setSignatureValidator(ISignatureValidator)
66
70
*/
67
71
public String getPublicKey ();
68
72
}
@@ -372,16 +376,16 @@ protected static void onPurchaseIntent(String itemId, PendingIntent purchaseInte
372
376
/**
373
377
* Called after the response to a
374
378
* {@link net.robotmedia.billing.request.GetPurchaseInformation} request is
375
- * received. Registers all transactions in local memory and confirms those
376
- * who can be confirmed automatically .
379
+ * received. Validates the signature asynchronously and calls
380
+ * {@link #onSignatureValidated(Context, String)} if successful .
377
381
*
378
382
* @param context
379
383
* @param signedData
380
384
* signed JSON data received from the Market Billing service.
381
385
* @param signature
382
386
* data signature.
383
387
*/
384
- protected static void onPurchaseStateChanged (Context context , String signedData , String signature ) {
388
+ protected static void onPurchaseStateChanged (final Context context , final String signedData , final String signature ) {
385
389
debug ("Purchase state changed" );
386
390
387
391
if (TextUtils .isEmpty (signedData )) {
@@ -391,19 +395,49 @@ protected static void onPurchaseStateChanged(Context context, String signedData,
391
395
debug (signedData );
392
396
}
393
397
394
- if (!debug ) {
395
- if (TextUtils .isEmpty (signature )) {
396
- Log .w (LOG_TAG , "Empty signature requires debug mode" );
397
- return ;
398
+ if (debug ) {
399
+ onSignatureValidated (context , signedData );
400
+ return ;
401
+ }
402
+
403
+ if (TextUtils .isEmpty (signature )) {
404
+ Log .w (LOG_TAG , "Empty signature requires debug mode" );
405
+ return ;
406
+ }
407
+ final ISignatureValidator validator = BillingController .validator != null ? BillingController .validator
408
+ : new DefaultSignatureValidator (BillingController .configuration );
409
+
410
+ // Use AsyncTask mostly in case the signature is validated remotely
411
+ new AsyncTask <Void , Void , Boolean >() {
412
+
413
+ @ Override
414
+ protected Boolean doInBackground (Void ... params ) {
415
+ return validator .validate (signedData , signature );
398
416
}
399
- final ISignatureValidator validator = BillingController .validator != null ? BillingController .validator
400
- : new DefaultSignatureValidator (BillingController .configuration );
401
- if (!validator .validate (signedData , signature )) {
402
- Log .w (LOG_TAG , "Signature does not match data." );
403
- return ;
417
+
418
+ @ Override
419
+ protected void onPostExecute (Boolean result ) {
420
+ if (result ) {
421
+ onSignatureValidated (context , signedData );
422
+ } else {
423
+ Log .w (LOG_TAG , "Signature does not match data." );
424
+ }
404
425
}
405
- }
406
426
427
+ }.execute ();
428
+ }
429
+
430
+ /**
431
+ * Called after the signature of a response to a
432
+ * {@link net.robotmedia.billing.request.GetPurchaseInformation} request has
433
+ * been validated. Registers all transactions in local memory and confirms
434
+ * those who can be confirmed automatically.
435
+ *
436
+ * @param context
437
+ * @param signedData
438
+ * signed JSON data received from the Market Billing service.
439
+ */
440
+ private static void onSignatureValidated (Context context , String signedData ) {
407
441
List <Transaction > purchases ;
408
442
try {
409
443
JSONObject jObject = new JSONObject (signedData );
@@ -432,7 +466,7 @@ protected static void onPurchaseStateChanged(Context context, String signedData,
432
466
if (!confirmations .isEmpty ()) {
433
467
final String [] notifyIds = confirmations .toArray (new String [confirmations .size ()]);
434
468
confirmNotifications (context , notifyIds );
435
- }
469
+ }
436
470
}
437
471
438
472
/**
0 commit comments