Add livedata for billing client state

Update existing code with livedata
This commit is contained in:
deeppandya
2023-09-08 02:03:59 -04:00
parent 7f9c142964
commit 838d1a7ae0
7 changed files with 222 additions and 158 deletions
@@ -294,7 +294,8 @@ public abstract class BraveActivity extends ChromeActivity
super.onResumeWithNative();
BraveActivityJni.get().restartStatsUpdater();
if (BraveVpnUtils.isBraveVpnFeatureEnable()) {
InAppPurchaseWrapper.getInstance().startBillingServiceConnection(BraveActivity.this);
InAppPurchaseWrapper.getInstance().startBillingServiceConnection(
BraveActivity.this, null);
BraveVpnNativeWorker.getInstance().addObserver(this);
BraveVpnUtils.reportBackgroundUsageP3A();
@@ -640,7 +641,7 @@ public abstract class BraveActivity extends ChromeActivity
InAppPurchaseWrapper.getInstance().queryPurchases();
LiveDataUtil.observeOnce(InAppPurchaseWrapper.getInstance().getPurchases(), purchases -> {
Purchase activePurchase = null;
for (Purchase purchase: purchases) {
for (Purchase purchase : purchases) {
if (purchase.getPurchaseState() == Purchase.PurchaseState.PURCHASED) {
activePurchase = purchase;
break;
@@ -96,7 +96,7 @@ public class BraveVpnPreferences extends BravePreferenceFragment implements Brav
SettingsUtils.addPreferencesFromResource(this, R.xml.brave_vpn_preferences);
if (BraveVpnUtils.isBraveVpnFeatureEnable()) {
InAppPurchaseWrapper.getInstance().startBillingServiceConnection(getActivity());
InAppPurchaseWrapper.getInstance().startBillingServiceConnection(getActivity(), null);
}
mVpnSwitch = (ChromeSwitchPreference) findPreference(PREF_VPN_SWITCH);
@@ -373,7 +373,7 @@ public class BraveVpnPreferences extends BravePreferenceFragment implements Brav
LiveDataUtil.observeOnce(InAppPurchaseWrapper.getInstance().getPurchases(), purchases -> {
mBraveVpnPrefModel = new BraveVpnPrefModel();
Purchase activePurchase = null;
for (Purchase purchase: purchases) {
for (Purchase purchase : purchases) {
if (purchase.getPurchaseState() == Purchase.PurchaseState.PURCHASED) {
activePurchase = purchase;
break;
@@ -96,34 +96,40 @@ public abstract class BraveVpnParentActivity
InAppPurchaseWrapper.getInstance().queryPurchases();
LiveDataUtil.observeOnce(InAppPurchaseWrapper.getInstance().getPurchases(), purchases -> {
Purchase activePurchase = null;
for (Purchase purchase: purchases) {
for (Purchase purchase : purchases) {
if (purchase.getPurchaseState() == Purchase.PurchaseState.PURCHASED) {
activePurchase = purchase;
break;
}
}
Log.e("BraveVPN", "verifySubscription 1");
if (activePurchase != null) {
Log.e("BraveVPN", "verifySubscription 2");
mBraveVpnPrefModel.setPurchaseToken(activePurchase.getPurchaseToken());
mBraveVpnPrefModel.setProductId(activePurchase.getProducts().get(0).toString());
BraveVpnNativeWorker.getInstance().verifyPurchaseToken(
mBraveVpnPrefModel.getPurchaseToken(), mBraveVpnPrefModel.getProductId(),
BraveVpnUtils.SUBSCRIPTION_PARAM_TEXT, getPackageName());
} else {
Log.e("BraveVPN", "verifySubscription 3");
if (!mIsVerification) {
BraveVpnApiResponseUtils.queryPurchaseFailed(BraveVpnParentActivity.this);
} else {
BraveVpnUtils.dismissProgressDialog();
}
Log.e("BraveVPN", "verifySubscription 4");
BraveVpnUtils.dismissProgressDialog();
}
});
}
@Override
public void onVerifyPurchaseToken(String jsonResponse, boolean isSuccess) {
Log.e("BraveVPN", "onVerifyPurchaseToken 1");
if (isSuccess && mBraveVpnPrefModel != null) {
Log.e("BraveVPN", "onVerifyPurchaseToken 2");
Long purchaseExpiry = BraveVpnUtils.getPurchaseExpiryDate(jsonResponse);
int paymentState = BraveVpnUtils.getPaymentState(jsonResponse);
if (purchaseExpiry > 0 && purchaseExpiry >= System.currentTimeMillis()) {
Log.e("BraveVPN", "onVerifyPurchaseToken 3");
BraveVpnPrefUtils.setPurchaseToken(mBraveVpnPrefModel.getPurchaseToken());
BraveVpnPrefUtils.setProductId(mBraveVpnPrefModel.getProductId());
BraveVpnPrefUtils.setPurchaseExpiry(purchaseExpiry);
@@ -143,16 +149,20 @@ public abstract class BraveVpnParentActivity
BraveVpnUtils.dismissProgressDialog();
}
} else {
Log.e("BraveVPN", "onVerifyPurchaseToken 4");
BraveVpnApiResponseUtils.queryPurchaseFailed(BraveVpnParentActivity.this);
if (mIsVerification) {
Log.e("BraveVPN", "onVerifyPurchaseToken 5");
mIsVerification = false;
showRestoreMenu(false);
BraveVpnUtils.dismissProgressDialog();
} else {
Log.e("BraveVPN", "onVerifyPurchaseToken 6");
BraveVpnUtils.openBraveVpnPlansActivity(BraveVpnParentActivity.this);
}
}
} else {
Log.e("BraveVPN", "onVerifyPurchaseToken 7");
BraveVpnUtils.dismissProgressDialog();
}
};
@@ -18,16 +18,19 @@ import android.widget.TextView;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.widget.Toolbar;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.viewpager.widget.ViewPager;
import com.android.billingclient.api.ProductDetails;
import com.android.billingclient.api.SkuDetails;
import com.google.android.material.tabs.TabLayout;
import org.chromium.chrome.R;
import org.chromium.base.Log;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.firstrun.BraveFirstRunFlowSequencer;
import org.chromium.chrome.browser.util.BraveConstants;
import org.chromium.chrome.browser.util.LiveDataUtil;
import org.chromium.chrome.browser.vpn.BraveVpnNativeWorker;
import org.chromium.chrome.browser.vpn.adapters.BraveVpnPlanPagerAdapter;
import org.chromium.chrome.browser.vpn.utils.BraveVpnUtils;
@@ -45,6 +48,9 @@ public class BraveVpnPlansActivity extends BraveVpnParentActivity {
private LinearLayout mMonthlySelectorLayout;
private LinearLayout mYearlySelectorLayout;
private MutableLiveData<Boolean> _billingConnectionState = new MutableLiveData();
private LiveData<Boolean> billingConnectionState = _billingConnectionState;
@Override
public void onResumeWithNative() {
super.onResumeWithNative();
@@ -60,11 +66,7 @@ public class BraveVpnPlansActivity extends BraveVpnParentActivity {
private void initializeViews() {
setContentView(R.layout.activity_brave_vpn_plan);
if (BraveVpnUtils.isBraveVpnFeatureEnable() && !InAppPurchaseWrapper.getInstance().isBillingClientReady()) {
InAppPurchaseWrapper.getInstance().startBillingServiceConnection(
BraveVpnPlansActivity.this);
}
Log.e("BraveVPN", "BraveVpnPlansActivity initializeViews");
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
@@ -95,125 +97,154 @@ public class BraveVpnPlansActivity extends BraveVpnParentActivity {
findViewById(R.id.monthly_subscription_amount_text);
mMonthlySelectorLayout = findViewById(R.id.monthly_selector_layout);
InAppPurchaseWrapper.getInstance().queryProductDetailsAsync(
InAppPurchaseWrapper.SubscriptionType.MONTHLY,
new InAppPurchaseWrapper.QueryProductDetailsResponse() {
@Override
public void onProductDetails(Map<String, ProductDetails> productDetailsMap) {
Log.e("BraveVPN", "queryProductDetailsAsync MONTHLY 1");
ProductDetails monthlyProductDetails = productDetailsMap.get(
InAppPurchaseWrapper.getInstance().getProductId(
InAppPurchaseWrapper.SubscriptionType.MONTHLY));
Log.e("BraveVPN", "queryProductDetailsAsync MONTHLY 2");
if (monthlyProductDetails != null) {
Log.e("BraveVPN", "queryProductDetailsAsync MONTHLY 3");
mMonthlySelectorLayout.setOnClickListener(v
-> InAppPurchaseWrapper.getInstance().initiatePurchase(
BraveVpnPlansActivity.this, monthlyProductDetails));
if (monthlyProductDetails.getSubscriptionOfferDetails() != null) {
monthlySubscriptionAmountText.setText(
String.format(getResources().getString(
R.string.monthly_subscription_amount),
monthlyProductDetails.getSubscriptionOfferDetails()
.get(0)
.getPricingPhases()
.getPricingPhaseList()
.get(0)
.getFormattedPrice()));
}
}
}
});
TextView yearlySubscriptionAmountText = findViewById(R.id.yearly_subscription_amount_text);
mYearlySelectorLayout = findViewById(R.id.yearly_selector_layout);
InAppPurchaseWrapper.getInstance().queryProductDetailsAsync(
InAppPurchaseWrapper.SubscriptionType.YEARLY,
new InAppPurchaseWrapper.QueryProductDetailsResponse() {
@Override
public void onProductDetails(Map<String, ProductDetails> productDetailsMap) {
ProductDetails yearlyProductDetails = productDetailsMap.get(
InAppPurchaseWrapper.getInstance().getProductId(
InAppPurchaseWrapper.SubscriptionType.YEARLY));
if (yearlyProductDetails != null) {
mYearlySelectorLayout.setOnClickListener(v
-> InAppPurchaseWrapper.getInstance().initiatePurchase(
BraveVpnPlansActivity.this, yearlyProductDetails));
if (yearlyProductDetails.getSubscriptionOfferDetails() != null) {
yearlySubscriptionAmountText.setText(
String.format(getResources().getString(
R.string.yearly_subscription_amount),
yearlyProductDetails.getSubscriptionOfferDetails()
.get(0)
.getPricingPhases()
.getPricingPhaseList()
.get(0)
.getFormattedPrice()));
LiveDataUtil.observeOnce(billingConnectionState, isConnected -> {
Log.e("BraveVPN", "LiveDataUtil.observeOnce : " + isConnected);
if (isConnected) {
Log.e("BraveVPN", "LiveDataUtil.observeOnce isConnected");
InAppPurchaseWrapper.getInstance().queryProductDetailsAsync(
InAppPurchaseWrapper.SubscriptionType.MONTHLY,
new InAppPurchaseWrapper.QueryProductDetailsResponse() {
@Override
public void onProductDetails(
Map<String, ProductDetails> productDetailsMap) {
Log.e("BraveVPN", "queryProductDetailsAsync MONTHLY 1");
ProductDetails monthlyProductDetails = productDetailsMap.get(
InAppPurchaseWrapper.getInstance().getProductId(
InAppPurchaseWrapper.SubscriptionType.MONTHLY));
Log.e("BraveVPN", "queryProductDetailsAsync MONTHLY 2");
if (monthlyProductDetails != null) {
runOnUiThread(new Runnable() {
@Override
public void run() {
Log.e("BraveVPN", "queryProductDetailsAsync MONTHLY 3");
mMonthlySelectorLayout.setOnClickListener(v
-> InAppPurchaseWrapper.getInstance()
.initiatePurchase(
BraveVpnPlansActivity.this,
monthlyProductDetails));
if (monthlyProductDetails.getSubscriptionOfferDetails()
!= null
&& monthlyProductDetails
.getSubscriptionOfferDetails()
.stream()
.findFirst()
.isPresent()
&& monthlyProductDetails
.getSubscriptionOfferDetails()
.stream()
.findFirst()
.get()
.getPricingPhases()
.getPricingPhaseList()
.stream()
.findFirst()
.isPresent()) {
String monthlyProductPrice =
monthlyProductDetails
.getSubscriptionOfferDetails()
.stream()
.findFirst()
.get()
.getPricingPhases()
.getPricingPhaseList()
.stream()
.findFirst()
.get()
.getFormattedPrice();
monthlySubscriptionAmountText.setText(String.format(
getResources().getString(
R.string.monthly_subscription_amount),
monthlyProductPrice));
}
}
});
}
}
}
}
});
});
// SkuDetails monthlySkuDetails = InAppPurchaseWrapper.getInstance().getSkuDetails(
// getPackageName().equals(BraveConstants.BRAVE_PRODUCTION_PACKAGE_NAME)
// ? InAppPurchaseWrapper.RELEASE_MONTHLY_SUBSCRIPTION
// : InAppPurchaseWrapper.NIGHTLY_MONTHLY_SUBSCRIPTION);
// SkuDetails yearlySkuDetails = InAppPurchaseWrapper.getInstance().getSkuDetails(
// getPackageName().equals(BraveConstants.BRAVE_PRODUCTION_PACKAGE_NAME)
// ? InAppPurchaseWrapper.RELEASE_YEARLY_SUBSCRIPTION
// : InAppPurchaseWrapper.NIGHTLY_YEARLY_SUBSCRIPTION);
// if (monthlySkuDetails != null && yearlySkuDetails != null) {
// mMonthlySelectorLayout = findViewById(R.id.monthly_selector_layout);
// mMonthlySelectorLayout.setOnClickListener(new View.OnClickListener() {
// @Override
// public void onClick(View v) {
// InAppPurchaseWrapper.getInstance().purchase(
// BraveVpnPlansActivity.this, monthlySkuDetails);
// }
// });
// TextView monthlySubscriptionAmountText =
// findViewById(R.id.monthly_subscription_amount_text);
// monthlySubscriptionAmountText.setText(
// String.format(getResources().getString(R.string.monthly_subscription_amount),
// monthlySkuDetails.getPrice()));
// mYearlySelectorLayout = findViewById(R.id.yearly_selector_layout);
// mYearlySelectorLayout.setOnClickListener(new View.OnClickListener() {
// @Override
// public void onClick(View v) {
// InAppPurchaseWrapper.getInstance().purchase(
// BraveVpnPlansActivity.this, yearlySkuDetails);
// }
// });
// TextView yearlySubscriptionAmountText =
// findViewById(R.id.yearly_subscription_amount_text);
// yearlySubscriptionAmountText.setText(
// String.format(getResources().getString(R.string.yearly_subscription_amount),
// yearlySkuDetails.getPrice()));
// BraveVpnUtils.showProgressDialog(BraveVpnPlansActivity.this,
// getResources().getString(R.string.vpn_connect_text));
// mIsVerification = true;
// verifySubscription();
// } else {
// Toast.makeText(BraveVpnPlansActivity.this, R.string.purchased_failed,
// Toast.LENGTH_LONG)
// .show();
// }
InAppPurchaseWrapper.getInstance().queryProductDetailsAsync(
InAppPurchaseWrapper.SubscriptionType.YEARLY,
new InAppPurchaseWrapper.QueryProductDetailsResponse() {
@Override
public void onProductDetails(
Map<String, ProductDetails> productDetailsMap) {
Log.e("BraveVPN", "queryProductDetailsAsync YEARLY 1");
ProductDetails yearlyProductDetails = productDetailsMap.get(
InAppPurchaseWrapper.getInstance().getProductId(
InAppPurchaseWrapper.SubscriptionType.YEARLY));
Log.e("BraveVPN", "queryProductDetailsAsync YEARLY 2");
if (yearlyProductDetails != null) {
runOnUiThread(new Runnable() {
@Override
public void run() {
Log.e("BraveVPN", "queryProductDetailsAsync YEARLY 3");
mYearlySelectorLayout.setOnClickListener(v
-> InAppPurchaseWrapper.getInstance()
.initiatePurchase(
BraveVpnPlansActivity.this,
yearlyProductDetails));
if (yearlyProductDetails.getSubscriptionOfferDetails()
!= null
&& yearlyProductDetails
.getSubscriptionOfferDetails()
.stream()
.findFirst()
.isPresent()
&& yearlyProductDetails
.getSubscriptionOfferDetails()
.stream()
.findFirst()
.get()
.getPricingPhases()
.getPricingPhaseList()
.stream()
.findFirst()
.isPresent()) {
String yearlyProductPrice =
yearlyProductDetails
.getSubscriptionOfferDetails()
.stream()
.findFirst()
.get()
.getPricingPhases()
.getPricingPhaseList()
.stream()
.findFirst()
.get()
.getFormattedPrice();
yearlySubscriptionAmountText.setText(String.format(
getResources().getString(
R.string.yearly_subscription_amount),
yearlyProductPrice));
}
}
});
}
}
});
}
});
}
@Override
public void finishNativeInitialization() {
super.finishNativeInitialization();
BraveVpnUtils.showProgressDialog(
BraveVpnPlansActivity.this, getResources().getString(R.string.vpn_connect_text));
mIsVerification = true;
verifySubscription();
Log.e("BraveVPN", "BraveVpnPlansActivity finishNativeInitialization");
if (BraveVpnUtils.isBraveVpnFeatureEnable()) {
InAppPurchaseWrapper.getInstance().startBillingServiceConnection(
BraveVpnPlansActivity.this, _billingConnectionState);
}
LiveDataUtil.observeOnce(billingConnectionState, isConnected -> {
if (isConnected) {
BraveVpnUtils.showProgressDialog(BraveVpnPlansActivity.this,
getResources().getString(R.string.vpn_connect_text));
mIsVerification = true;
verifySubscription();
}
});
}
@Override
@@ -17,9 +17,12 @@ import android.widget.TextView;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.widget.Toolbar;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.firstrun.BraveFirstRunFlowSequencer;
import org.chromium.chrome.browser.util.LiveDataUtil;
import org.chromium.chrome.browser.vpn.BraveVpnNativeWorker;
import org.chromium.chrome.browser.vpn.models.BraveVpnPrefModel;
import org.chromium.chrome.browser.vpn.utils.BraveVpnUtils;
@@ -34,6 +37,9 @@ public class BraveVpnProfileActivity extends BraveVpnParentActivity {
private ProgressBar mProfileProgress;
private LinearLayout mProfileLayout;
private MutableLiveData<Boolean> _billingConnectionState = new MutableLiveData();
private LiveData<Boolean> billingConnectionState = _billingConnectionState;
@Override
public void onResumeWithNative() {
super.onResumeWithNative();
@@ -49,9 +55,9 @@ public class BraveVpnProfileActivity extends BraveVpnParentActivity {
private void initializeViews() {
setContentView(R.layout.activity_brave_vpn_profile);
if (BraveVpnUtils.isBraveVpnFeatureEnable() && !InAppPurchaseWrapper.getInstance().isBillingClientReady()) {
if (BraveVpnUtils.isBraveVpnFeatureEnable()) {
InAppPurchaseWrapper.getInstance().startBillingServiceConnection(
BraveVpnProfileActivity.this);
BraveVpnProfileActivity.this, _billingConnectionState);
}
Toolbar toolbar = findViewById(R.id.toolbar);
@@ -74,12 +80,14 @@ public class BraveVpnProfileActivity extends BraveVpnParentActivity {
public void onClick(View v) {
BraveVpnUtils.showProgressDialog(BraveVpnProfileActivity.this,
getResources().getString(R.string.vpn_connect_text));
if (BraveVpnNativeWorker.getInstance().isPurchasedUser()) {
mBraveVpnPrefModel = new BraveVpnPrefModel();
BraveVpnNativeWorker.getInstance().getSubscriberCredentialV12();
} else {
verifySubscription();
}
LiveDataUtil.observeOnce(billingConnectionState, isConnected -> {
if (BraveVpnNativeWorker.getInstance().isPurchasedUser()) {
mBraveVpnPrefModel = new BraveVpnPrefModel();
BraveVpnNativeWorker.getInstance().getSubscriberCredentialV12();
} else {
verifySubscription();
}
});
}
});
@@ -37,7 +37,6 @@ public class BraveVpnApiResponseUtils {
}
Toast.makeText(activity, R.string.purchase_token_verification_failed, Toast.LENGTH_LONG)
.show();
BraveVpnUtils.dismissProgressDialog();
}
public static void handleOnGetSubscriberCredential(Activity activity, boolean isSuccess) {
@@ -98,25 +98,46 @@ public class InAppPurchaseWrapper {
return mBillingClient != null && mBillingClient.isReady();
}
public void startBillingServiceConnection(Context context) {
public void startBillingServiceConnection(
Context context, MutableLiveData<Boolean> billingClientConnectionState) {
mBillingClient = BillingClient.newBuilder(context)
.enablePendingPurchases()
.setListener(getPurchasesUpdatedListener(context))
.build();
connectToBillingService();
}
public void connectToBillingService() {
if (!mBillingClient.isReady()) {
try {
mBillingClient.startConnection(billingClientStateListener);
mBillingClient.startConnection(new BillingClientStateListener() {
private int retryCount;
@Override
public void onBillingServiceDisconnected() {
retryCount++;
if (retryCount <= 3) {
startBillingServiceConnection(context, billingClientConnectionState);
}
}
@Override
public void onBillingSetupFinished(@NonNull BillingResult billingResult) {
if (billingResult.getResponseCode()
== BillingClient.BillingResponseCode.OK) {
retryCount = 0;
if (billingClientConnectionState != null) {
Log.e("BraveVPN", "billingClientConnectionState != null");
billingClientConnectionState.postValue(true);
}
}
}
});
} catch (IllegalStateException exc) {
// That prevents a crash that some users experience
// https://github.com/brave/brave-browser/issues/27751.
// It's unknown what causes it, we tried to add retries, but it
// didn't help.
Log.e(TAG, "connectToBillingService " + exc.getMessage());
Log.e(TAG, "startBillingServiceConnection " + exc.getMessage());
}
} else {
if (billingClientConnectionState != null) {
billingClientConnectionState.postValue(mBillingClient.getConnectionState()
== BillingClient.ConnectionState.CONNECTED);
}
}
}
@@ -165,6 +186,10 @@ public class InAppPurchaseWrapper {
productDetails.put(productDetail.getProductId(), productDetail);
}
queryProductDetailsResponse.onProductDetails(productDetails);
} else {
Log.e(TAG,
"queryProductDetailsAsync failed"
+ billingResult.getDebugMessage());
}
});
}
@@ -173,11 +198,18 @@ public class InAppPurchaseWrapper {
mBillingClient.queryPurchasesAsync(QueryPurchasesParams.newBuilder()
.setProductType(BillingClient.ProductType.SUBS)
.build(),
(billingResult, list) -> { setPurchases(list); });
(billingResult, list) -> {
if (billingResult.getResponseCode() == OK) {
setPurchases(list);
} else {
Log.e(TAG, "queryPurchases failed" + billingResult.getDebugMessage());
}
});
}
public void initiatePurchase(Activity activity, ProductDetails productDetails) {
String offerToken = productDetails.getSubscriptionOfferDetails().get(0).getOfferToken();
Log.e("BraveVPN", "offerToken : " + offerToken);
List<BillingFlowParams.ProductDetailsParams> productDetailsParamsList = new ArrayList<>();
productDetailsParamsList.add(BillingFlowParams.ProductDetailsParams.newBuilder()
.setProductDetails(productDetails)
@@ -243,7 +275,7 @@ public class InAppPurchaseWrapper {
} else if (billingResult.getResponseCode()
== BillingClient.BillingResponseCode.SERVICE_DISCONNECTED
&& mRetryCount < 5) {
connectToBillingService();
// startBillingServiceConnection(context);
mRetryCount++;
} else if (billingResult.getResponseCode()
== BillingClient.BillingResponseCode.USER_CANCELED) {
@@ -258,21 +290,4 @@ public class InAppPurchaseWrapper {
}
};
}
BillingClientStateListener billingClientStateListener = new BillingClientStateListener() {
private int retryCount;
@Override
public void onBillingServiceDisconnected() {
retryCount++;
if (retryCount <= 3) {
connectToBillingService();
}
}
@Override
public void onBillingSetupFinished(@NonNull BillingResult billingResult) {
if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
retryCount = 0;
}
}
};
}