Welcome to mirror list, hosted at ThFree Co, Russian Federation.

PurchaseUtils.java « purchase « maps « mapswithme « com « src « android - github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 29370962839e89e24be9c8d9d4c264e4e98800f7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
package com.mapswithme.maps.purchase;

import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.text.TextUtils;

import com.android.billingclient.api.Purchase;
import com.android.billingclient.api.SkuDetails;
import com.mapswithme.maps.R;
import com.mapswithme.maps.dialog.AlertDialog;
import com.mapswithme.util.CrashlyticsUtils;
import com.mapswithme.util.Utils;
import com.mapswithme.util.log.Logger;
import com.mapswithme.util.log.LoggerFactory;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.List;

public class PurchaseUtils
{
  final static int REQ_CODE_PRODUCT_DETAILS_FAILURE = 1;
  final static int REQ_CODE_PAYMENT_FAILURE = 2;
  final static int REQ_CODE_VALIDATION_SERVER_ERROR = 3;
  final static int REQ_CODE_START_TRANSACTION_FAILURE = 4;
  final static int REQ_CODE_PING_FAILURE = 5;
  public static final int REQ_CODE_CHECK_INVALID_SUBS_DIALOG = 6;
  public static final int REQ_CODE_BMK_SUBS_SUCCESS_DIALOG = 7;
  public final static int REQ_CODE_PAY_CONTINUE_SUBSCRIPTION = 8;
  public final static int REQ_CODE_PAY_BOOKMARK = 9;
  public final static int REQ_CODE_PAY_SUBSCRIPTION = 10;
  public static final String DIALOG_TAG_CHECK_INVALID_SUBS = "check_invalid_subs";
  public static final String DIALOG_TAG_BMK_SUBSCRIPTION_SUCCESS = "bmk_subscription_success";
  public static final String EXTRA_IS_SUBSCRIPTION = "extra_is_subscription";

  final static int WEEKS_IN_YEAR = 52;
  final static int MONTHS_IN_YEAR = 12;
  private static final Logger LOGGER = LoggerFactory.INSTANCE.getLogger(LoggerFactory.Type.BILLING);
  private static final String TAG = PurchaseUtils.class.getSimpleName();
  static final int REQ_CODE_NO_NETWORK_CONNECTION_DIALOG = 11;
  static final String NO_NETWORK_CONNECTION_DIALOG_TAG = "no_network_connection_dialog_tag";

  private PurchaseUtils()
  {
    // Utility class.
  }

  @NonNull
  static String parseToken(@NonNull String purchaseData)
  {
    try
    {
      return new Purchase(purchaseData, null).getPurchaseToken();
    }
    catch (JSONException e)
    {
      throw new IllegalArgumentException("Failed to parse purchase token!");
    }
  }

  @NonNull
  public static String parseOrderId(@NonNull String purchaseData)
  {
    try
    {
      return new Purchase(purchaseData, null).getOrderId();
    }
    catch (JSONException e)
    {
      throw new IllegalArgumentException("Failed to parse purchase order id!");
    }
  }

  @NonNull
  static ProductDetails toProductDetails(@NonNull SkuDetails skuDetails)
  {
    float price = normalizePrice(skuDetails.getPriceAmountMicros());
    String currencyCode = skuDetails.getPriceCurrencyCode();
    return new ProductDetails(skuDetails.getSku(), price, currencyCode, skuDetails.getTitle());
  }

  @NonNull
  public static String toProductDetailsBundle(@NonNull List<SkuDetails> skuDetails)
  {
    if (skuDetails.isEmpty())
      return "";

    JSONObject bundleJson = new JSONObject();
    for (SkuDetails details: skuDetails)
    {
      JSONObject priceJson = new JSONObject();
      try
      {
        float price = normalizePrice(details.getPriceAmountMicros());
        String currencyCode = details.getPriceCurrencyCode();
        priceJson.put("price_string", Utils.formatCurrencyString(price, currencyCode));
        bundleJson.put(details.getSku(), priceJson);
      }
      catch (Exception e)
      {
        Logger logger = LoggerFactory.INSTANCE.getLogger(LoggerFactory.Type.BILLING);
        String tag = PurchaseUtils.class.getSimpleName();
        String msg = "Failed to form product details bundle for '" + details + "': ";
        logger.e(tag, msg, e);
        CrashlyticsUtils.logException(new RuntimeException(msg, e));
        return "";
      }
    }

    return bundleJson.toString();
  }

  private static float normalizePrice(long priceMicros)
  {
    return priceMicros / 1000000f;
  }

  static boolean hasIncorrectSkuDetails(@NonNull List<SkuDetails> skuDetails)
  {
    for (SkuDetails each : skuDetails)
    {
      if (Period.getInstance(each.getSubscriptionPeriod()) == null)
      {
        String msg = "Unsupported subscription period: '" + each.getSubscriptionPeriod() + "'";
        CrashlyticsUtils.logException(new IllegalStateException(msg));
        LOGGER.e(TAG, msg);
        return true;
      }
    }
    return false;
  }

  static void showPaymentFailureDialog(@NonNull Fragment fragment, @Nullable String tag)
  {
    AlertDialog alertDialog = new AlertDialog.Builder()
        .setReqCode(PurchaseUtils.REQ_CODE_PAYMENT_FAILURE)
        .setTitleId(R.string.bookmarks_convert_error_title)
        .setMessageId(R.string.purchase_error_subtitle)
        .setPositiveBtnId(R.string.back)
        .build();
    alertDialog.show(fragment, tag);
  }

  static void showProductDetailsFailureDialog(@NonNull Fragment fragment, @NonNull String tag)
  {
    AlertDialog alertDialog = new AlertDialog.Builder()
        .setReqCode(PurchaseUtils.REQ_CODE_PRODUCT_DETAILS_FAILURE)
        .setTitleId(R.string.bookmarks_convert_error_title)
        .setMessageId(R.string.discovery_button_other_error_message)
        .setPositiveBtnId(R.string.ok)
        .build();
    alertDialog.show(fragment, tag);
  }

  static void showPingFailureDialog(@NonNull Fragment fragment)
  {
    AlertDialog alertDialog = new AlertDialog.Builder()
        .setReqCode(PurchaseUtils.REQ_CODE_PING_FAILURE)
        .setTitleId(R.string.subscription_error_ping_title)
        .setMessageId(R.string.subscription_error_message)
        .setPositiveBtnId(R.string.ok)
        .build();
    alertDialog.show(fragment, null);
  }

  static void showNoConnectionDialog(@NonNull Fragment fragment)
  {
    AlertDialog dialog = new AlertDialog.Builder()
        .setTitleId(R.string.common_check_internet_connection_dialog_title)
        .setMessageId(R.string.common_check_internet_connection_dialog)
        .setPositiveBtnId(R.string.try_again)
        .setNegativeBtnId(R.string.cancel)
        .setFragManagerStrategyType(AlertDialog.FragManagerStrategyType.ACTIVITY_FRAGMENT_MANAGER)
        .setReqCode(REQ_CODE_NO_NETWORK_CONNECTION_DIALOG)
        .build();
    dialog.setTargetFragment(fragment, REQ_CODE_NO_NETWORK_CONNECTION_DIALOG);
    dialog.show(fragment, NO_NETWORK_CONNECTION_DIALOG_TAG);
  }

  enum Period
  {
    // Order is important.
    P1Y,
    P1M,
    P1W;

    @Nullable
    static Period getInstance(@Nullable String subscriptionPeriod)
    {
      for (Period each : values())
      {
        if (TextUtils.equals(each.name(), subscriptionPeriod))
          return each;
      }
      return null;
    }
  }
}