Updated IAB

pull/207/head
M66B 4 years ago
parent f1443332f6
commit 30a995323f

@ -343,17 +343,17 @@ dependencies {
def lbm_version = "1.1.0"
def swiperefresh_version = "1.2.0-alpha01"
def documentfile_version = "1.1.0-alpha01"
def lifecycle_version = "2.4.0" // 2.5.0-alpha03
def lifecycle_version = "2.4.0" // 2.5.0-alpha04
def lifecycle_extensions_version = "2.2.0"
def room_version = "2.4.2" // 2.5.0-alpha01
def sqlite_version = "2.2.0" // 2.3.0-alpha01
def requery_version = "3.36.0"
def paging_version = "2.1.2" // 3.1.0
def paging_version = "2.1.2" // 3.1.1
def preference_version = "1.2.0"
def work_version = "2.7.1" // 2.8.0-alpha01
def exif_version = "1.3.3"
def biometric_version = "1.2.0-alpha04"
def billingclient_version = "3.0.3" // 4.0.0
def billingclient_version = "4.1.0"
def javamail_version = "1.6.7"
def jsoup_version = "1.14.3"
def css_version = "0.9.29"

@ -52,6 +52,7 @@ import com.android.billingclient.api.BillingResult;
import com.android.billingclient.api.ConsumeParams;
import com.android.billingclient.api.ConsumeResponseListener;
import com.android.billingclient.api.Purchase;
import com.android.billingclient.api.PurchasesResponseListener;
import com.android.billingclient.api.PurchasesUpdatedListener;
import com.android.billingclient.api.SkuDetails;
import com.android.billingclient.api.SkuDetailsParams;
@ -155,16 +156,19 @@ public class ActivityBilling extends ActivityBase implements /*PurchasesUpdatedL
}
@NonNull
static String getSkuPro() {
if (BuildConfig.DEBUG)
static String getSkuPro(Context context) {
if (isTesting(context))
return SKU_TEST;
else
return BuildConfig.APPLICATION_ID + ".pro";
}
static boolean isTesting(Context context) {
if (context == null)
return false;
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
return (BuildConfig.TEST_RELEASE && prefs.getBoolean("test_iab", false));
return (BuildConfig.DEBUG && BuildConfig.TEST_RELEASE &&
prefs.getBoolean("test_iab", false));
}
private static String getChallenge(Context context) throws NoSuchAlgorithmException {
@ -230,7 +234,7 @@ public class ActivityBilling extends ActivityBase implements /*PurchasesUpdatedL
private void onPurchase(Intent intent) {
if (Helper.isPlayStoreInstall() || isTesting(this)) {
String skuPro = getSkuPro();
String skuPro = getSkuPro(this);
Log.i("IAB purchase SKU=" + skuPro);
/*
SkuDetailsParams.Builder builder = SkuDetailsParams.newBuilder();
@ -271,12 +275,16 @@ public class ActivityBilling extends ActivityBase implements /*PurchasesUpdatedL
}
/*
private void onPurchaseConsume(Intent intent) {
Purchase.PurchasesResult result = billingClient.queryPurchases(BillingClient.SkuType.INAPP);
billingClient.queryPurchasesAsync(BillingClient.SkuType.INAPP, new PurchasesResponseListener() {
@Override
public void onQueryPurchasesResponse(@NonNull BillingResult result, @NonNull List<Purchase> list) {
if (result.getResponseCode() == BillingClient.BillingResponseCode.OK) {
for (Purchase purchase : result.getPurchasesList())
for (Purchase purchase : list)
consumePurchase(purchase);
} else
reportError(result.getBillingResult(), "IAB onPurchaseConsume");
reportError(result, "IAB onPurchaseConsume");
}
});
}
private void onPurchaseError(Intent intent) {
@ -336,6 +344,7 @@ public class ActivityBilling extends ActivityBase implements /*PurchasesUpdatedL
@Override
public void onPurchasesUpdated(BillingResult result, @Nullable List<Purchase> purchases) {
Log.i("IAB purchases updated");
if (result.getResponseCode() == BillingClient.BillingResponseCode.OK)
checkPurchases(purchases);
else
@ -343,11 +352,16 @@ public class ActivityBilling extends ActivityBase implements /*PurchasesUpdatedL
}
private void queryPurchases() {
Purchase.PurchasesResult result = billingClient.queryPurchases(BillingClient.SkuType.INAPP);
billingClient.queryPurchasesAsync(BillingClient.SkuType.INAPP, new PurchasesResponseListener() {
@Override
public void onQueryPurchasesResponse(@NonNull BillingResult result, @NonNull List<Purchase> list) {
if (result.getResponseCode() == BillingClient.BillingResponseCode.OK)
checkPurchases(result.getPurchasesList());
checkPurchases(list);
else
reportError(result.getBillingResult(), "IAB query purchases");
reportError(result, "IAB query purchases");
}
});
}
*/
interface IBillingListener {
@ -388,13 +402,13 @@ public class ActivityBilling extends ActivityBase implements /*PurchasesUpdatedL
Log.i("IAB purchases=" + (purchases == null ? null : purchases.size()));
List<String> query = new ArrayList<>();
query.add(getSkuPro());
query.add(getSkuPro(this));
if (purchases != null) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
SharedPreferences.Editor editor = prefs.edit();
if (prefs.getBoolean("play_store", true)) {
long cached = prefs.getLong(getSkuPro() + ".cached", 0);
long cached = prefs.getLong(getSkuPro(this) + ".cached", 0);
if (cached + MAX_SKU_CACHE_DURATION < new Date().getTime()) {
Log.i("IAB cache expired=" + new Date(cached));
editor.remove("pro");
@ -403,11 +417,12 @@ public class ActivityBilling extends ActivityBase implements /*PurchasesUpdatedL
}
for (Purchase purchase : purchases)
for (String sku : purchase.getSkus())
try {
query.remove(purchase.getSku());
query.remove(sku);
long time = purchase.getPurchaseTime();
Log.i("IAB SKU=" + purchase.getSku() +
Log.i("IAB SKU=" + sku +
" purchased=" + isPurchased(purchase) +
" valid=" + isPurchaseValid(purchase) +
" time=" + new Date(time));
@ -415,9 +430,9 @@ public class ActivityBilling extends ActivityBase implements /*PurchasesUpdatedL
for (IBillingListener listener : listeners)
if (isPurchaseValid(purchase))
listener.onPurchased(purchase.getSku(), true);
listener.onPurchased(sku, true);
else
listener.onPurchasePending(purchase.getSku());
listener.onPurchasePending(sku);
if (isPurchased(purchase)) {
byte[] decodedKey = Base64.decode(getString(R.string.public_key), Base64.DEFAULT);
@ -426,13 +441,13 @@ public class ActivityBilling extends ActivityBase implements /*PurchasesUpdatedL
Signature sig = Signature.getInstance("SHA1withRSA");
sig.initVerify(publicKey);
sig.update(purchase.getOriginalJson().getBytes());
if (SKU_TEST.equals(purchase.getSku()) ||
if (SKU_TEST.equals(sku) ||
sig.verify(Base64.decode(purchase.getSignature(), Base64.DEFAULT))) {
Log.i("IAB valid signature");
if (getSkuPro().equals(purchase.getSku())) {
if (getSkuPro(this).equals(sku)) {
if (isPurchaseValid(purchase)) {
editor.putBoolean("pro", true);
editor.putLong(purchase.getSku() + ".cached", new Date().getTime());
editor.putLong(sku + ".cached", new Date().getTime());
}
if (!purchase.isAcknowledged())
@ -479,7 +494,8 @@ public class ActivityBilling extends ActivityBase implements /*PurchasesUpdatedL
}
private void consumePurchase(final Purchase purchase) {
Log.i("IAB consuming SKU=" + purchase.getSku());
for (String sku : purchase.getSkus()) {
Log.i("IAB consuming SKU=" + sku);
ConsumeParams params = ConsumeParams.newBuilder()
.setPurchaseToken(purchase.getPurchaseToken())
.build();
@ -488,15 +504,17 @@ public class ActivityBilling extends ActivityBase implements /*PurchasesUpdatedL
public void onConsumeResponse(@NonNull BillingResult result, @NonNull String purchaseToken) {
if (result.getResponseCode() == BillingClient.BillingResponseCode.OK) {
for (IBillingListener listener : listeners)
listener.onPurchased(purchase.getSku(), false);
listener.onPurchased(sku, false);
} else
reportError(result, "IAB consuming SKU=" + purchase.getSku());
reportError(result, "IAB consuming SKU=" + sku);
}
});
}
}
private void acknowledgePurchase(final Purchase purchase, int retry) {
Log.i("IAB acknowledging purchase SKU=" + purchase.getSku());
for (String sku : purchase.getSkus()) {
Log.i("IAB acknowledging purchase SKU=" + sku);
AcknowledgePurchaseParams params =
AcknowledgePurchaseParams.newBuilder()
.setPurchaseToken(purchase.getPurchaseToken())
@ -508,11 +526,11 @@ public class ActivityBilling extends ActivityBase implements /*PurchasesUpdatedL
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ActivityBilling.this);
SharedPreferences.Editor editor = prefs.edit();
editor.putBoolean("pro", true);
editor.putLong(purchase.getSku() + ".cached", new Date().getTime());
editor.putLong(sku + ".cached", new Date().getTime());
editor.apply();
for (IBillingListener listener : listeners)
listener.onPurchased(purchase.getSku(), true);
listener.onPurchased(sku, true);
WidgetUnified.updateData(ActivityBilling.this);
} else {
@ -524,11 +542,12 @@ public class ActivityBilling extends ActivityBase implements /*PurchasesUpdatedL
}
}, (retry + 1) * 10 * 1000L);
} else
reportError(result, "IAB acknowledged SKU=" + purchase.getSku());
reportError(result, "IAB acknowledged SKU=" + sku);
}
}
});
}
}
private boolean isPurchased(Purchase purchase) {
return (purchase.getPurchaseState() == Purchase.PurchaseState.PURCHASED);
@ -537,7 +556,7 @@ public class ActivityBilling extends ActivityBase implements /*PurchasesUpdatedL
private boolean isPurchaseValid(Purchase purchase) {
return (isPurchased(purchase) &&
(purchase.isAcknowledged() ||
SKU_TEST.equals(purchase.getSku()) ||
purchase.getSkus().contains(SKU_TEST) ||
purchase.getPurchaseTime() + MAX_SKU_NOACK_DURATION > new Date().getTime()));
}

@ -1444,7 +1444,7 @@ public class FragmentOptionsMisc extends FragmentBase implements SharedPreferenc
(external == null ? null : external.getAbsolutePath()) + (emulated ? " emulated" : ""));
swExactAlarms.setEnabled(AlarmManagerCompatEx.canScheduleExactAlarms(getContext()));
swTestIab.setVisibility(BuildConfig.TEST_RELEASE ? View.VISIBLE : View.GONE);
swTestIab.setVisibility(BuildConfig.DEBUG && BuildConfig.TEST_RELEASE ? View.VISIBLE : View.GONE);
PreferenceManager.getDefaultSharedPreferences(getContext()).registerOnSharedPreferenceChangeListener(this);

@ -221,7 +221,7 @@ public class FragmentPro extends FragmentBase implements SharedPreferences.OnSha
@Override
public void onSkuDetails(String sku, String price) {
if (!ActivityBilling.getSkuPro().equals(sku))
if (!ActivityBilling.getSkuPro(getContext()).equals(sku))
return;
post(new Runnable() {
@ -236,7 +236,7 @@ public class FragmentPro extends FragmentBase implements SharedPreferences.OnSha
@Override
public void onPurchasePending(String sku) {
if (!ActivityBilling.getSkuPro().equals(sku))
if (!ActivityBilling.getSkuPro(getContext()).equals(sku))
return;
post(new Runnable() {
@ -250,7 +250,7 @@ public class FragmentPro extends FragmentBase implements SharedPreferences.OnSha
@Override
public void onPurchased(String sku, boolean purchased) {
if (!ActivityBilling.getSkuPro().equals(sku))
if (!ActivityBilling.getSkuPro(getContext()).equals(sku))
return;
post(new Runnable() {

@ -52,6 +52,7 @@ import com.android.billingclient.api.BillingResult;
import com.android.billingclient.api.ConsumeParams;
import com.android.billingclient.api.ConsumeResponseListener;
import com.android.billingclient.api.Purchase;
import com.android.billingclient.api.PurchasesResponseListener;
import com.android.billingclient.api.PurchasesUpdatedListener;
import com.android.billingclient.api.SkuDetails;
import com.android.billingclient.api.SkuDetailsParams;
@ -155,16 +156,19 @@ public class ActivityBilling extends ActivityBase implements PurchasesUpdatedLis
}
@NonNull
static String getSkuPro() {
if (BuildConfig.DEBUG)
static String getSkuPro(Context context) {
if (isTesting(context))
return SKU_TEST;
else
return BuildConfig.APPLICATION_ID + ".pro";
}
static boolean isTesting(Context context) {
if (context == null)
return false;
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
return (BuildConfig.TEST_RELEASE && prefs.getBoolean("test_iab", false));
return (BuildConfig.DEBUG && BuildConfig.TEST_RELEASE &&
prefs.getBoolean("test_iab", false));
}
private static String getChallenge(Context context) throws NoSuchAlgorithmException {
@ -230,7 +234,7 @@ public class ActivityBilling extends ActivityBase implements PurchasesUpdatedLis
private void onPurchase(Intent intent) {
if (Helper.isPlayStoreInstall() || isTesting(this)) {
String skuPro = getSkuPro();
String skuPro = getSkuPro(this);
Log.i("IAB purchase SKU=" + skuPro);
SkuDetailsParams.Builder builder = SkuDetailsParams.newBuilder();
@ -270,12 +274,16 @@ public class ActivityBilling extends ActivityBase implements PurchasesUpdatedLis
}
private void onPurchaseConsume(Intent intent) {
Purchase.PurchasesResult result = billingClient.queryPurchases(BillingClient.SkuType.INAPP);
billingClient.queryPurchasesAsync(BillingClient.SkuType.INAPP, new PurchasesResponseListener() {
@Override
public void onQueryPurchasesResponse(@NonNull BillingResult result, @NonNull List<Purchase> list) {
if (result.getResponseCode() == BillingClient.BillingResponseCode.OK) {
for (Purchase purchase : result.getPurchasesList())
for (Purchase purchase : list)
consumePurchase(purchase);
} else
reportError(result.getBillingResult(), "IAB onPurchaseConsume");
reportError(result, "IAB onPurchaseConsume");
}
});
}
private void onPurchaseError(Intent intent) {
@ -335,6 +343,7 @@ public class ActivityBilling extends ActivityBase implements PurchasesUpdatedLis
@Override
public void onPurchasesUpdated(BillingResult result, @Nullable List<Purchase> purchases) {
Log.i("IAB purchases updated");
if (result.getResponseCode() == BillingClient.BillingResponseCode.OK)
checkPurchases(purchases);
else
@ -342,11 +351,16 @@ public class ActivityBilling extends ActivityBase implements PurchasesUpdatedLis
}
private void queryPurchases() {
Purchase.PurchasesResult result = billingClient.queryPurchases(BillingClient.SkuType.INAPP);
billingClient.queryPurchasesAsync(BillingClient.SkuType.INAPP, new PurchasesResponseListener() {
@Override
public void onQueryPurchasesResponse(@NonNull BillingResult result, @NonNull List<Purchase> list) {
if (result.getResponseCode() == BillingClient.BillingResponseCode.OK)
checkPurchases(result.getPurchasesList());
checkPurchases(list);
else
reportError(result.getBillingResult(), "IAB query purchases");
reportError(result, "IAB query purchases");
}
});
}
interface IBillingListener {
@ -387,13 +401,13 @@ public class ActivityBilling extends ActivityBase implements PurchasesUpdatedLis
Log.i("IAB purchases=" + (purchases == null ? null : purchases.size()));
List<String> query = new ArrayList<>();
query.add(getSkuPro());
query.add(getSkuPro(this));
if (purchases != null) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
SharedPreferences.Editor editor = prefs.edit();
if (prefs.getBoolean("play_store", true)) {
long cached = prefs.getLong(getSkuPro() + ".cached", 0);
long cached = prefs.getLong(getSkuPro(this) + ".cached", 0);
if (cached + MAX_SKU_CACHE_DURATION < new Date().getTime()) {
Log.i("IAB cache expired=" + new Date(cached));
editor.remove("pro");
@ -402,11 +416,12 @@ public class ActivityBilling extends ActivityBase implements PurchasesUpdatedLis
}
for (Purchase purchase : purchases)
for (String sku : purchase.getSkus())
try {
query.remove(purchase.getSku());
query.remove(sku);
long time = purchase.getPurchaseTime();
Log.i("IAB SKU=" + purchase.getSku() +
Log.i("IAB SKU=" + sku +
" purchased=" + isPurchased(purchase) +
" valid=" + isPurchaseValid(purchase) +
" time=" + new Date(time));
@ -414,9 +429,9 @@ public class ActivityBilling extends ActivityBase implements PurchasesUpdatedLis
for (IBillingListener listener : listeners)
if (isPurchaseValid(purchase))
listener.onPurchased(purchase.getSku(), true);
listener.onPurchased(sku, true);
else
listener.onPurchasePending(purchase.getSku());
listener.onPurchasePending(sku);
if (isPurchased(purchase)) {
byte[] decodedKey = Base64.decode(getString(R.string.public_key), Base64.DEFAULT);
@ -425,13 +440,13 @@ public class ActivityBilling extends ActivityBase implements PurchasesUpdatedLis
Signature sig = Signature.getInstance("SHA1withRSA");
sig.initVerify(publicKey);
sig.update(purchase.getOriginalJson().getBytes());
if (SKU_TEST.equals(purchase.getSku()) ||
if (SKU_TEST.equals(sku) ||
sig.verify(Base64.decode(purchase.getSignature(), Base64.DEFAULT))) {
Log.i("IAB valid signature");
if (getSkuPro().equals(purchase.getSku())) {
if (getSkuPro(this).equals(sku)) {
if (isPurchaseValid(purchase)) {
editor.putBoolean("pro", true);
editor.putLong(purchase.getSku() + ".cached", new Date().getTime());
editor.putLong(sku + ".cached", new Date().getTime());
}
if (!purchase.isAcknowledged())
@ -478,7 +493,8 @@ public class ActivityBilling extends ActivityBase implements PurchasesUpdatedLis
}
private void consumePurchase(final Purchase purchase) {
Log.i("IAB consuming SKU=" + purchase.getSku());
for (String sku : purchase.getSkus()) {
Log.i("IAB consuming SKU=" + sku);
ConsumeParams params = ConsumeParams.newBuilder()
.setPurchaseToken(purchase.getPurchaseToken())
.build();
@ -487,15 +503,17 @@ public class ActivityBilling extends ActivityBase implements PurchasesUpdatedLis
public void onConsumeResponse(@NonNull BillingResult result, @NonNull String purchaseToken) {
if (result.getResponseCode() == BillingClient.BillingResponseCode.OK) {
for (IBillingListener listener : listeners)
listener.onPurchased(purchase.getSku(), false);
listener.onPurchased(sku, false);
} else
reportError(result, "IAB consuming SKU=" + purchase.getSku());
reportError(result, "IAB consuming SKU=" + sku);
}
});
}
}
private void acknowledgePurchase(final Purchase purchase, int retry) {
Log.i("IAB acknowledging purchase SKU=" + purchase.getSku());
for (String sku : purchase.getSkus()) {
Log.i("IAB acknowledging purchase SKU=" + sku);
AcknowledgePurchaseParams params =
AcknowledgePurchaseParams.newBuilder()
.setPurchaseToken(purchase.getPurchaseToken())
@ -507,11 +525,11 @@ public class ActivityBilling extends ActivityBase implements PurchasesUpdatedLis
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ActivityBilling.this);
SharedPreferences.Editor editor = prefs.edit();
editor.putBoolean("pro", true);
editor.putLong(purchase.getSku() + ".cached", new Date().getTime());
editor.putLong(sku + ".cached", new Date().getTime());
editor.apply();
for (IBillingListener listener : listeners)
listener.onPurchased(purchase.getSku(), true);
listener.onPurchased(sku, true);
WidgetUnified.updateData(ActivityBilling.this);
} else {
@ -523,11 +541,12 @@ public class ActivityBilling extends ActivityBase implements PurchasesUpdatedLis
}
}, (retry + 1) * 10 * 1000L);
} else
reportError(result, "IAB acknowledged SKU=" + purchase.getSku());
reportError(result, "IAB acknowledged SKU=" + sku);
}
}
});
}
}
private boolean isPurchased(Purchase purchase) {
return (purchase.getPurchaseState() == Purchase.PurchaseState.PURCHASED);
@ -536,7 +555,7 @@ public class ActivityBilling extends ActivityBase implements PurchasesUpdatedLis
private boolean isPurchaseValid(Purchase purchase) {
return (isPurchased(purchase) &&
(purchase.isAcknowledged() ||
SKU_TEST.equals(purchase.getSku()) ||
purchase.getSkus().contains(SKU_TEST) ||
purchase.getPurchaseTime() + MAX_SKU_NOACK_DURATION > new Date().getTime()));
}

Loading…
Cancel
Save