NetGuard/app/src/main/java/eu/faircode/netguard/IAB.java

241 lines
8.6 KiB
Java
Raw Normal View History

2015-11-14 20:25:05 +00:00
package eu.faircode.netguard;
/*
This file is part of NetGuard.
NetGuard is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
NetGuard is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with NetGuard. If not, see <http://www.gnu.org/licenses/>.
2018-12-31 16:12:49 +00:00
Copyright 2015-2019 by Marcel Bokhorst (M66B)
2015-11-14 20:25:05 +00:00
*/
import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
2015-12-30 08:58:21 +00:00
import android.content.SharedPreferences;
2015-11-14 20:25:05 +00:00
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
2020-01-09 18:24:55 +00:00
import androidx.preference.PreferenceManager;
2015-11-14 20:25:05 +00:00
import com.android.vending.billing.IInAppBillingService;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
2015-12-31 15:55:39 +00:00
import java.util.List;
2015-11-14 20:25:05 +00:00
public class IAB implements ServiceConnection {
private static final String TAG = "NetGuard.IAB";
2015-11-14 20:25:05 +00:00
private Context context;
2015-12-30 08:00:34 +00:00
private Delegate delegate;
2015-11-14 20:25:05 +00:00
private IInAppBillingService service = null;
2015-11-18 16:56:05 +00:00
private static final int IAB_VERSION = 3;
2015-11-14 20:25:05 +00:00
2015-12-30 08:00:34 +00:00
public interface Delegate {
2016-02-18 08:16:18 +00:00
void onReady(IAB iab);
2015-12-30 08:00:34 +00:00
}
public IAB(Delegate delegate, Context context) {
2016-02-13 12:21:18 +00:00
this.context = context.getApplicationContext();
2015-12-30 08:00:34 +00:00
this.delegate = delegate;
2015-11-14 20:25:05 +00:00
}
public void bind() {
2015-12-30 08:58:21 +00:00
Log.i(TAG, "Bind");
Intent serviceIntent = new Intent("com.android.vending.billing.InAppBillingService.BIND");
serviceIntent.setPackage("com.android.vending");
context.bindService(serviceIntent, this, Context.BIND_AUTO_CREATE);
2015-11-14 20:25:05 +00:00
}
public void unbind() {
2015-12-30 08:58:21 +00:00
if (service != null) {
Log.i(TAG, "Unbind");
context.unbindService(this);
service = null;
}
2015-11-14 20:25:05 +00:00
}
@Override
public void onServiceConnected(ComponentName name, IBinder binder) {
Log.i(TAG, "Connected");
2015-12-30 08:58:21 +00:00
service = IInAppBillingService.Stub.asInterface(binder);
2016-02-18 08:16:18 +00:00
delegate.onReady(this);
2015-11-14 20:25:05 +00:00
}
@Override
public void onServiceDisconnected(ComponentName name) {
Log.i(TAG, "Disconnected");
service = null;
}
2015-12-30 08:00:34 +00:00
public boolean isAvailable(String sku) throws RemoteException, JSONException {
// Get available SKUs
ArrayList<String> skuList = new ArrayList<>();
skuList.add(sku);
Bundle query = new Bundle();
query.putStringArrayList("ITEM_ID_LIST", skuList);
Bundle bundle = service.getSkuDetails(IAB_VERSION, context.getPackageName(), "inapp", query);
Log.i(TAG, "getSkuDetails");
Util.logBundle(bundle);
int response = (bundle == null ? -1 : bundle.getInt("RESPONSE_CODE", -1));
Log.i(TAG, "Response=" + getResult(response));
if (response != 0)
throw new IllegalArgumentException(getResult(response));
// Check available SKUs
boolean found = false;
ArrayList<String> details = bundle.getStringArrayList("DETAILS_LIST");
if (details != null)
for (String item : details) {
JSONObject object = new JSONObject(item);
if (sku.equals(object.getString("productId"))) {
found = true;
break;
2015-11-14 20:25:05 +00:00
}
2015-12-30 08:00:34 +00:00
}
Log.i(TAG, sku + "=" + found);
2015-11-14 20:25:05 +00:00
2015-12-30 08:00:34 +00:00
return found;
2015-11-14 20:25:05 +00:00
}
2015-12-31 15:55:39 +00:00
public void updatePurchases() throws RemoteException {
// Get purchases
2020-04-24 14:52:51 +00:00
List<String> skus = new ArrayList<>();
skus.addAll(getPurchases("inapp"));
skus.addAll(getPurchases("subs"));
2015-12-31 15:55:39 +00:00
SharedPreferences prefs = context.getSharedPreferences("IAB", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = prefs.edit();
for (String product : prefs.getAll().keySet())
2017-01-06 18:20:00 +00:00
if (!ActivityPro.SKU_DONATION.equals(product)) {
Log.i(TAG, "removing SKU=" + product);
2015-12-31 18:31:34 +00:00
editor.remove(product);
2017-01-06 18:20:00 +00:00
}
2015-12-31 15:55:39 +00:00
for (String sku : skus) {
2017-01-06 18:20:00 +00:00
Log.i(TAG, "adding SKU=" + sku);
2015-12-31 15:55:39 +00:00
editor.putBoolean(sku, true);
}
editor.apply();
}
2020-04-24 14:52:51 +00:00
public boolean isPurchased(String sku, String type) throws RemoteException {
return getPurchases(type).contains(sku);
2015-12-31 15:55:39 +00:00
}
2020-04-24 14:52:51 +00:00
public List<String> getPurchases(String type) throws RemoteException {
2015-12-30 08:00:34 +00:00
// Get purchases
2020-04-24 14:52:51 +00:00
Bundle bundle = service.getPurchases(IAB_VERSION, context.getPackageName(), type, null);
2015-12-30 08:00:34 +00:00
Log.i(TAG, "getPurchases");
Util.logBundle(bundle);
int response = (bundle == null ? -1 : bundle.getInt("RESPONSE_CODE", -1));
Log.i(TAG, "Response=" + getResult(response));
if (response != 0)
throw new IllegalArgumentException(getResult(response));
2015-12-31 15:55:39 +00:00
ArrayList<String> details = bundle.getStringArrayList("INAPP_PURCHASE_ITEM_LIST");
return (details == null ? new ArrayList<String>() : details);
2015-11-14 20:25:05 +00:00
}
2016-07-23 08:09:09 +00:00
public PendingIntent getBuyIntent(String sku, boolean subscription) throws RemoteException {
2016-02-18 08:16:18 +00:00
if (service == null)
return null;
2016-07-23 08:09:09 +00:00
Bundle bundle = service.getBuyIntent(IAB_VERSION, context.getPackageName(), sku, subscription ? "subs" : "inapp", "netguard");
Log.i(TAG, "getBuyIntent sku=" + sku + " subscription=" + subscription);
2015-12-30 08:00:34 +00:00
Util.logBundle(bundle);
int response = (bundle == null ? -1 : bundle.getInt("RESPONSE_CODE", -1));
Log.i(TAG, "Response=" + getResult(response));
if (response != 0)
throw new IllegalArgumentException(getResult(response));
if (!bundle.containsKey("BUY_INTENT"))
throw new IllegalArgumentException("BUY_INTENT missing");
return bundle.getParcelable("BUY_INTENT");
2015-11-14 20:25:05 +00:00
}
2015-12-30 08:58:21 +00:00
public static void setBought(String sku, Context context) {
Log.i(TAG, "Bought " + sku);
SharedPreferences prefs = context.getSharedPreferences("IAB", Context.MODE_PRIVATE);
prefs.edit().putBoolean(sku, true).apply();
}
2016-01-01 18:03:41 +00:00
public static boolean isPurchased(String sku, Context context) {
2017-07-06 05:50:54 +00:00
try {
if (Util.isDebuggable(context)) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
return !prefs.getBoolean("debug_iab", false);
}
2017-07-06 05:50:54 +00:00
SharedPreferences prefs = context.getSharedPreferences("IAB", Context.MODE_PRIVATE);
if (ActivityPro.SKU_SUPPORT1.equals(sku) || ActivityPro.SKU_SUPPORT2.equals(sku))
return prefs.getBoolean(sku, false);
2017-07-06 05:50:54 +00:00
return (prefs.getBoolean(sku, false) ||
prefs.getBoolean(ActivityPro.SKU_PRO1, false) ||
2020-05-18 13:39:59 +00:00
prefs.getBoolean(ActivityPro.SKU_SUPPORT1, false) ||
prefs.getBoolean(ActivityPro.SKU_SUPPORT2, false) ||
2017-07-06 05:50:54 +00:00
prefs.getBoolean(ActivityPro.SKU_DONATION, false));
} catch (SecurityException ignored) {
return false;
}
2015-12-30 08:58:21 +00:00
}
2016-07-24 16:02:56 +00:00
public static boolean isPurchasedAny(Context context) {
2017-07-06 05:50:54 +00:00
try {
if (Util.isDebuggable(context)) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
2018-07-08 07:56:55 +00:00
return !(prefs.getBoolean("debug_iab", false));
2017-07-06 05:50:54 +00:00
}
2017-07-06 05:50:54 +00:00
SharedPreferences prefs = context.getSharedPreferences("IAB", Context.MODE_PRIVATE);
for (String key : prefs.getAll().keySet())
if (prefs.getBoolean(key, false))
return true;
return false;
} catch (SecurityException ignored) {
return false;
}
2016-07-24 16:02:56 +00:00
}
2015-12-27 09:44:50 +00:00
public static String getResult(int responseCode) {
2015-11-14 20:25:05 +00:00
switch (responseCode) {
case 0:
return "OK";
case 1:
return "USER_CANCELED";
case 2:
return "SERVICE_UNAVAILABLE";
case 3:
return "BILLING_UNAVAILABLE";
case 4:
return "ITEM_UNAVAILABLE";
case 5:
return "DEVELOPER_ERROR";
case 6:
return "ERROR";
case 7:
return "ITEM_ALREADY_OWNED";
case 8:
return "ITEM_NOT_OWNED";
default:
return Integer.toString(responseCode);
}
}
}