aboutsummaryrefslogtreecommitdiff
path: root/app/src/main/kotlin/com/pitchedapps/frost/utils
diff options
context:
space:
mode:
Diffstat (limited to 'app/src/main/kotlin/com/pitchedapps/frost/utils')
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/utils/L.kt6
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/utils/Prefs.kt12
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/utils/Utils.kt30
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/utils/iab/IABDialogs.kt95
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/utils/iab/IabBinder.kt188
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/utils/iab/Key.kt33
6 files changed, 11 insertions, 353 deletions
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/utils/L.kt b/app/src/main/kotlin/com/pitchedapps/frost/utils/L.kt
index a108745c..4f31f5f5 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/utils/L.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/utils/L.kt
@@ -2,7 +2,7 @@ package com.pitchedapps.frost.utils
import android.util.Log
import ca.allanwang.kau.logging.KauLogger
-import com.crashlytics.android.Crashlytics
+import com.bugsnag.android.Bugsnag
import com.pitchedapps.frost.BuildConfig
@@ -34,9 +34,9 @@ object L : KauLogger("Frost", {
super.logImpl(priority, message, t)
else {
if (message != null)
- Crashlytics.log(priority, tag, message)
+ Bugsnag.leaveBreadcrumb(message)
if (t != null)
- Crashlytics.logException(t)
+ Bugsnag.notify(t)
}
}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/utils/Prefs.kt b/app/src/main/kotlin/com/pitchedapps/frost/utils/Prefs.kt
index 26d7894e..95a5f39b 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/utils/Prefs.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/utils/Prefs.kt
@@ -135,19 +135,9 @@ object Prefs : KPref() {
var enablePip: Boolean by kpref("enable_pip", true)
- /**
- * Cache like value to determine if user has or had pro
- * In most cases, [com.pitchedapps.frost.utils.iab.IS_FROST_PRO] should be looked at instead
- * This has been renamed to pro for short, but keep in mind that it only reflects the value
- * of when it was previously verified
- */
- var pro: Boolean by kpref("previously_pro", false)
-
- var debugPro: Boolean by kpref("debug_pro", false)
-
var verboseLogging: Boolean by kpref("verbose_logging", false)
- var analytics: Boolean by kpref("analytics", true)
+ var analytics: Boolean by kpref("analytics", false)
var overlayEnabled: Boolean by kpref("overlay_enabled", true)
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/utils/Utils.kt b/app/src/main/kotlin/com/pitchedapps/frost/utils/Utils.kt
index d73f29e9..b1b129fb 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/utils/Utils.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/utils/Utils.kt
@@ -23,15 +23,12 @@ import ca.allanwang.kau.mediapicker.createPrivateMediaFile
import ca.allanwang.kau.utils.*
import ca.allanwang.kau.xml.showChangelog
import com.afollestad.materialdialogs.MaterialDialog
-import com.crashlytics.android.answers.Answers
-import com.crashlytics.android.answers.CustomEvent
import com.pitchedapps.frost.BuildConfig
import com.pitchedapps.frost.R
import com.pitchedapps.frost.activities.*
import com.pitchedapps.frost.dbflow.CookieModel
import com.pitchedapps.frost.facebook.*
import com.pitchedapps.frost.facebook.FbUrlFormatter.Companion.VIDEO_REDIRECT
-import com.pitchedapps.frost.utils.iab.IS_FROST_PRO
import org.apache.commons.text.StringEscapeUtils
import org.jsoup.Jsoup
import org.jsoup.nodes.Element
@@ -175,29 +172,19 @@ inline fun Activity.setFrostColors(builder: ActivityThemeUtils.() -> Unit) {
themer.theme(this)
}
-fun frostAnswers(action: Answers.() -> Unit) {
- if (BuildConfig.DEBUG || !Prefs.analytics) return
- Answers.getInstance().action()
-}
-fun frostAnswersCustom(name: String, vararg events: Pair<String, Any>) {
- frostAnswers {
- logCustom(CustomEvent("Frost $name").apply {
- events.forEach { (key, value) ->
- if (value is Number) putCustomAttribute(key, value)
- else putCustomAttribute(key, value.toString())
- }
- })
- }
+fun frostEvent(name: String, vararg events: Pair<String, Any>) {
+ // todo bind
+ L.v { "Event: $name ${events.joinToString(", ")}" }
}
/**
* Helper method to quietly keep track of throwable issues
*/
-fun Throwable?.logFrostAnswers(text: String) {
+fun Throwable?.logFrostEvent(text: String) {
val msg = if (this == null) text else "$text: $message"
L.e { msg }
- frostAnswersCustom("Errors", "text" to text, "message" to (this?.message ?: "NA"))
+ frostEvent("Errors", "text" to text, "message" to (this?.message ?: "NA"))
}
fun Activity.frostSnackbar(@StringRes text: Int, builder: Snackbar.() -> Unit = {}) = snackbar(text, Snackbar.LENGTH_LONG, frostSnackbar(builder))
@@ -291,10 +278,6 @@ inline val String?.isExplicitIntent
fun Context.frostChangelog() = showChangelog(R.xml.frost_changelog, Prefs.textColor) {
theme()
- if (System.currentTimeMillis() - Prefs.installDate > 2592000000) { //show after 1 month
- neutralText(R.string.kau_rate)
- onNeutral { _, _ -> startPlayStoreLink(R.string.play_store_package_id) }
- }
}
fun Context.frostUriFromFile(file: File): Uri =
@@ -311,7 +294,8 @@ inline fun Context.sendFrostEmail(subjectId: String, crossinline builder: EmailB
fun EmailBuilder.addFrostDetails() {
addItem("Prev version", Prefs.prevVersionCode.toString())
- val proTag = if (IS_FROST_PRO) "TY" else "FP"
+ val proTag = "FO"
+// if (IS_FROST_PRO) "TY" else "FP"
addItem("Random Frost ID", "${Prefs.frostId}-$proTag")
addItem("Locale", Locale.getDefault().displayName)
}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/utils/iab/IABDialogs.kt b/app/src/main/kotlin/com/pitchedapps/frost/utils/iab/IABDialogs.kt
deleted file mode 100644
index 15d707a9..00000000
--- a/app/src/main/kotlin/com/pitchedapps/frost/utils/iab/IABDialogs.kt
+++ /dev/null
@@ -1,95 +0,0 @@
-package com.pitchedapps.frost.utils.iab
-
-import android.app.Activity
-import ca.allanwang.kau.utils.restart
-import ca.allanwang.kau.utils.startLink
-import ca.allanwang.kau.utils.startPlayStoreLink
-import ca.allanwang.kau.utils.string
-import com.crashlytics.android.answers.PurchaseEvent
-import com.pitchedapps.frost.R
-import com.pitchedapps.frost.activities.SettingsActivity
-import com.pitchedapps.frost.utils.*
-
-/**
- * Created by Allan Wang on 2017-06-30.
- */
-
-private fun playStoreLog(text: String) {
- L.e(Throwable(text)) { "IAB Play Store Exception" }
-}
-
-/**
- * Properly restart an activity
- */
-private fun Activity.playRestart() {
- if (this is SettingsActivity) {
- setResult(REQUEST_RESTART)
- finish()
- } else restart()
-}
-
-fun Activity?.playStoreNoLongerPro() {
- Prefs.pro = false
- L.d { "IAB No longer pro" }
- frostAnswers {
- logPurchase(PurchaseEvent()
- .putCustomAttribute("result", "no longer pro")
- .putSuccess(false))
- }
- if (this == null) return
- materialDialogThemed {
- title(R.string.uh_oh)
- content(R.string.play_store_not_pro)
- positiveText(R.string.reload)
- dismissListener {
- this@playStoreNoLongerPro.playRestart()
- }
- }
-}
-
-fun Activity?.playStoreFoundPro() {
- Prefs.pro = true
- L.d { "Found pro" }
- if (this == null) return
- materialDialogThemed {
- title(R.string.found_pro)
- content(R.string.found_pro_desc)
- positiveText(R.string.reload)
- dismissListener {
- this@playStoreFoundPro.playRestart()
- }
- }
-}
-
-fun Activity.playStorePurchaseUnsupported() {
- L.d { "Play store not found" }
- materialDialogThemed {
- title(R.string.uh_oh)
- content(R.string.play_store_unsupported)
- negativeText(R.string.kau_close)
- positiveText(R.string.kau_play_store)
- neutralText(R.string.paypal)
- onPositive { _, _ -> startPlayStoreLink(R.string.play_store_package_id) }
- onNeutral { _, _ -> startLink(string(R.string.dev_paypal)) }
- }
-}
-
-fun Activity.playStorePurchasedSuccessfully(key: String) {
- L.d { "Play store purchased $key successfully" }
- materialDialogThemed {
- title(R.string.play_thank_you)
- content(R.string.play_purchased_pro)
- positiveText(R.string.kau_ok)
- neutralText(R.string.kau_rate)
- onNeutral { _, _ -> startPlayStoreLink(R.string.play_store_package_id) }
- }
-}
-
-fun Activity.purchaseRestored() {
- L.d { "Purchase restored" }
- materialDialogThemed {
- title(R.string.play_thank_you)
- content(R.string.purchases_restored_with_pro)
- positiveText(R.string.kau_ok)
- }
-} \ No newline at end of file
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/utils/iab/IabBinder.kt b/app/src/main/kotlin/com/pitchedapps/frost/utils/iab/IabBinder.kt
deleted file mode 100644
index 568127a2..00000000
--- a/app/src/main/kotlin/com/pitchedapps/frost/utils/iab/IabBinder.kt
+++ /dev/null
@@ -1,188 +0,0 @@
-package com.pitchedapps.frost.utils.iab
-
-import android.app.Activity
-import android.content.Intent
-import com.anjlab.android.iab.v3.BillingProcessor
-import com.anjlab.android.iab.v3.TransactionDetails
-import com.crashlytics.android.answers.PurchaseEvent
-import com.pitchedapps.frost.BuildConfig
-import com.pitchedapps.frost.utils.L
-import com.pitchedapps.frost.utils.Prefs
-import com.pitchedapps.frost.utils.frostAnswers
-import com.pitchedapps.frost.utils.logFrostAnswers
-import org.jetbrains.anko.doAsync
-import org.jetbrains.anko.onComplete
-import org.jetbrains.anko.uiThread
-import java.lang.ref.WeakReference
-import java.math.BigDecimal
-import java.util.*
-
-/**
- * Created by Allan Wang on 2017-07-22.
- */
-private const val FROST_PRO = "frost_pro"
-
-/**
- * Implemented pro checker with a hook for debug builds
- * Use this when checking if the pro feature is enabled
- */
-inline val IS_FROST_PRO: Boolean
- get() = Prefs.pro || (BuildConfig.DEBUG && Prefs.debugPro)
-
-interface FrostBilling : BillingProcessor.IBillingHandler {
- fun Activity.onCreateBilling()
- fun onDestroyBilling()
- fun purchasePro()
- fun restorePurchases()
- fun onActivityResultBilling(requestCode: Int, resultCode: Int, data: Intent?): Boolean
-}
-
-abstract class IabBinder : FrostBilling {
-
- var bp: BillingProcessor? = null
- lateinit var activityRef: WeakReference<Activity>
- val activity
- get() = activityRef.get()
-
- final override fun Activity.onCreateBilling() {
- activityRef = WeakReference(this)
- doAsync {
- bp = BillingProcessor.newBillingProcessor(this@onCreateBilling, PUBLIC_BILLING_KEY, this@IabBinder)
- bp?.initialize()
- }
- }
-
- override fun onDestroyBilling() {
- activityRef.clear()
- bp?.release()
- bp = null
- }
-
- override fun onBillingInitialized() = L.i { "IAB initialized" }
-
- override fun onPurchaseHistoryRestored() = L.d { "IAB restored" }
-
- override fun onProductPurchased(productId: String, details: TransactionDetails?) {
- bp.doAsync {
- L.i { "IAB $productId purchased" }
- val listing = weakRef.get()?.getPurchaseListingDetails(productId) ?: return@doAsync
- val currency = try {
- Currency.getInstance(listing.currency)
- } catch (e: Exception) {
- null
- }
- frostAnswers {
- logPurchase(PurchaseEvent().apply {
- putItemId(productId)
- putSuccess(true)
- if (currency != null) {
- putCurrency(currency)
- putItemType(productId)
- putItemPrice(BigDecimal.valueOf(listing.priceValue))
- }
- })
- }
- }
- }
-
- override fun onBillingError(errorCode: Int, error: Throwable?) {
- frostAnswers {
- logPurchase(PurchaseEvent()
- .putCustomAttribute("result", errorCode.toString())
- .putSuccess(false))
- }
- error.logFrostAnswers("IAB error $errorCode")
- }
-
- override fun onActivityResultBilling(requestCode: Int, resultCode: Int, data: Intent?): Boolean = bp?.handleActivityResult(requestCode, resultCode, data)
- ?: false
-
- override fun purchasePro() {
- val bp = this.bp
- if (bp == null) {
- frostAnswers {
- logPurchase(PurchaseEvent()
- .putCustomAttribute("result", "null bp")
- .putSuccess(false))
- }
- L.eThrow("IAB null bp on purchase attempt")
- return
- }
- val a = activity ?: return
-
- if (!BillingProcessor.isIabServiceAvailable(a) || !bp.isInitialized || !bp.isOneTimePurchaseSupported)
- a.playStorePurchaseUnsupported()
- else
- bp.purchase(a, FROST_PRO)
- }
-
-}
-
-class IabSettings : IabBinder() {
-
- override fun onProductPurchased(productId: String, details: TransactionDetails?) {
- super.onProductPurchased(productId, details)
- activity?.playStorePurchasedSuccessfully(productId)
- }
-
- override fun onBillingError(errorCode: Int, error: Throwable?) {
- super.onBillingError(errorCode, error)
- L.e { "Billing error $errorCode ${error?.message}" }
- }
-
- /**
- * Attempts to get pro, or launch purchase flow if user doesn't have it
- */
- override fun restorePurchases() {
- bp.doAsync {
- val load = weakRef.get()?.loadOwnedPurchasesFromGoogle() ?: return@doAsync
- L.d { "IAB settings load from google $load" }
- uiThread {
- if (!(weakRef.get()?.isPurchased(FROST_PRO) ?: return@uiThread)) {
- if (Prefs.pro) activity.playStoreNoLongerPro()
- else purchasePro()
- } else {
- if (!Prefs.pro) activity.playStoreFoundPro()
- else activity?.purchaseRestored()
- }
- }
- }
- }
-}
-
-class IabMain : IabBinder() {
-
- override fun onBillingInitialized() {
- super.onBillingInitialized()
- restorePurchases()
- }
-
- override fun onPurchaseHistoryRestored() {
- super.onPurchaseHistoryRestored()
- restorePurchases()
- }
-
- private var restored = false
-
- /**
- * Checks for pro and only does so once
- * A null check is added but it should never happen
- * given that this is only called with bp is ready
- */
- override fun restorePurchases() {
- if (restored || bp == null) return
- restored = true
- bp.doAsync {
- val load = weakRef.get()?.loadOwnedPurchasesFromGoogle() ?: false
- L.d { "IAB main load from google $load" }
- onComplete {
- if (weakRef.get()?.isPurchased(FROST_PRO) != true) {
- if (Prefs.pro) activity.playStoreNoLongerPro()
- } else {
- if (!Prefs.pro) activity.playStoreFoundPro()
- }
- onDestroyBilling()
- }
- }
- }
-} \ No newline at end of file
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/utils/iab/Key.kt b/app/src/main/kotlin/com/pitchedapps/frost/utils/iab/Key.kt
deleted file mode 100644
index a21d8670..00000000
--- a/app/src/main/kotlin/com/pitchedapps/frost/utils/iab/Key.kt
+++ /dev/null
@@ -1,33 +0,0 @@
-package com.pitchedapps.frost.utils.iab
-
-/**
- * Created by Allan Wang on 2017-06-23.
- *
- * NOTE
- *
- * Since this is an open source project and all other components are essentially public,
- * I have decided to add the keys here too;
- * they can be reverse engineered relatively easily since they are constants anyways.
- * This is the public billing key from the play store
- */
-private const val play_key_1 = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAgyTZS"
-private const val play_key_2 = "K9Bd3ALpr9KJUsVGczP9CcPelWkdnJfNrrzu1EztJyrHRsGQ4"
-private const val play_key_3 = "QVWY9NZwc6Nrk9qdJlEdr8AJAxJ+JiwUqsj3/TxxUYm/G7q8Z"
-private const val play_key_4 = "7zo8jSkYZyzqwoAl2PDx2kleI4sZLkhCRLyE6dGQEZQmvJ6kk"
-private const val play_key_5 = "W12Gz3FagAM5luRGsoWZj40pJItUrGJA9euMWq4rMhVZv4mVk"
-private const val play_key_6 = "KFJB9/vhF/XGz7txpYlFxMESzXuKsbEDKmKCHzvySLq8Ki4N9"
-private const val play_key_7 = "DzbgUiw+VzA2KpSVp66JH3GEU8egO8i9SvAWeCPikuolooRVh"
-private const val play_key_8 = "jwfBV7gDxZztoLuvmQU6kXvCwRnRa+mkfUnBKKLkH1QIDAQAB"
-
-internal val PUBLIC_BILLING_KEY: String by lazy {
- StringBuilder()
- .append(play_key_1)
- .append(play_key_2)
- .append(play_key_3)
- .append(play_key_4)
- .append(play_key_5)
- .append(play_key_6)
- .append(play_key_7)
- .append(play_key_8)
- .toString()
-} \ No newline at end of file