improved analyzer events

This commit is contained in:
Mariotaku Lee 2017-01-07 19:16:17 +08:00
parent ac7af6abac
commit dd815fef84
12 changed files with 111 additions and 64 deletions

View File

@ -59,7 +59,7 @@ class GooglePlayInAppPurchaseActivity : BaseActivity(), BillingProcessor.IBillin
override fun onBillingInitialized() { override fun onBillingInitialized() {
// See https://github.com/anjlab/android-inapp-billing-v3/issues/156 // See https://github.com/anjlab/android-inapp-billing-v3/issues/156
if (intent.action == ACTION_RESTORE_PURCHASE) { if (intent.action == ACTION_RESTORE_PURCHASE) {
performRestorePurchase() getProductDetailsAndFinish()
} else { } else {
billingProcessor.purchase(this, productId) billingProcessor.purchase(this, productId)
} }
@ -91,10 +91,11 @@ class GooglePlayInAppPurchaseActivity : BaseActivity(), BillingProcessor.IBillin
finish() finish()
} }
private fun performRestorePurchase() {
private fun getProductDetailsAndFinish() {
executeAfterFragmentResumed { executeAfterFragmentResumed {
val weakThis = WeakReference(it as GooglePlayInAppPurchaseActivity) val weakThis = WeakReference(it as GooglePlayInAppPurchaseActivity)
val dfRef = WeakReference(ProgressDialogFragment.show(it.supportFragmentManager, "consume_purchase_progress")) val dfRef = WeakReference(ProgressDialogFragment.show(it.supportFragmentManager, TAG_PURCHASE_PROCESS))
task { task {
val activity = weakThis.get() ?: throw PurchaseException(BILLING_RESPONSE_RESULT_USER_CANCELED) val activity = weakThis.get() ?: throw PurchaseException(BILLING_RESPONSE_RESULT_USER_CANCELED)
val productId = activity.productId val productId = activity.productId
@ -116,38 +117,7 @@ class GooglePlayInAppPurchaseActivity : BaseActivity(), BillingProcessor.IBillin
}.alwaysUi { }.alwaysUi {
weakThis.get()?.executeAfterFragmentResumed { weakThis.get()?.executeAfterFragmentResumed {
val fm = weakThis.get()?.supportFragmentManager val fm = weakThis.get()?.supportFragmentManager
val df = dfRef.get() ?: (fm?.findFragmentByTag("consume_purchase_progress") as? DialogFragment) val df = dfRef.get() ?: (fm?.findFragmentByTag(TAG_PURCHASE_PROCESS) as? DialogFragment)
df?.dismiss()
}
}
}
}
private fun getProductDetailsAndFinish() {
executeAfterFragmentResumed {
val weakThis = WeakReference(it as GooglePlayInAppPurchaseActivity)
val dfRef = WeakReference(ProgressDialogFragment.show(it.supportFragmentManager, "consume_purchase_progress"))
task {
val activity = weakThis.get() ?: throw PurchaseException(BILLING_RESPONSE_RESULT_USER_CANCELED)
val bp = activity.billingProcessor
bp.loadOwnedPurchasesFromGoogle()
val skuDetails = bp.getPurchaseListingDetails(productId)
?: throw PurchaseException(BILLING_RESPONSE_RESULT_ERROR)
val transactionDetails = bp.getPurchaseTransactionDetails(productId)
?: throw PurchaseException(BILLING_RESPONSE_RESULT_ITEM_NOT_OWNED)
return@task Pair(skuDetails, transactionDetails)
}.successUi { result ->
weakThis.get()?.handlePurchased(result.first, result.second)
}.failUi { error ->
if (error is PurchaseException) {
weakThis.get()?.handleError(error.code)
} else {
weakThis.get()?.handleError(BILLING_RESPONSE_RESULT_ERROR)
}
}.alwaysUi {
weakThis.get()?.executeAfterFragmentResumed {
val fm = weakThis.get()?.supportFragmentManager
val df = dfRef.get() ?: (fm?.findFragmentByTag("consume_purchase_progress") as? DialogFragment)
df?.dismiss() df?.dismiss()
} }
} }
@ -170,6 +140,8 @@ class GooglePlayInAppPurchaseActivity : BaseActivity(), BillingProcessor.IBillin
class PurchaseException(val code: Int) : Exception() class PurchaseException(val code: Int) : Exception()
companion object { companion object {
private const val TAG_PURCHASE_PROCESS = "get_purchase_process"
const val EXTRA_PRODUCT_ID = "product_id" const val EXTRA_PRODUCT_ID = "product_id"
const val ACTION_RESTORE_PURCHASE = "${INTENT_PACKAGE_PREFIX}RESTORE_PURCHASE" const val ACTION_RESTORE_PURCHASE = "${INTENT_PACKAGE_PREFIX}RESTORE_PURCHASE"
} }

View File

@ -22,7 +22,6 @@ package org.mariotaku.twidere.util
import android.accounts.Account import android.accounts.Account
import android.accounts.AccountManager import android.accounts.AccountManager
import android.accounts.OnAccountsUpdateListener import android.accounts.OnAccountsUpdateListener
import android.app.Activity
import android.app.Application import android.app.Application
import android.os.Build import android.os.Build
import com.crashlytics.android.Crashlytics import com.crashlytics.android.Crashlytics
@ -33,10 +32,7 @@ import org.mariotaku.ktextension.configure
import org.mariotaku.twidere.BuildConfig import org.mariotaku.twidere.BuildConfig
import org.mariotaku.twidere.Constants import org.mariotaku.twidere.Constants
import org.mariotaku.twidere.TwidereConstants.ACCOUNT_TYPE import org.mariotaku.twidere.TwidereConstants.ACCOUNT_TYPE
import org.mariotaku.twidere.model.analyzer.Purchase import org.mariotaku.twidere.model.analyzer.*
import org.mariotaku.twidere.model.analyzer.Search
import org.mariotaku.twidere.model.analyzer.Share
import org.mariotaku.twidere.model.analyzer.SignIn
import java.math.BigDecimal import java.math.BigDecimal
import java.util.* import java.util.*
@ -85,10 +81,23 @@ class FabricAnalyzer : Analyzer(), Constants {
putAttributes(event) putAttributes(event)
}) })
} }
is Purchase -> { is PurchaseConfirm -> {
answers.logStartCheckout(configure(StartCheckoutEvent()) {
event.forEachValues { name, value ->
putCustomAttribute(name, value)
}
})
}
is PurchaseIntroduction -> {
answers.logAddToCart(configure(AddToCartEvent()) {
event.forEachValues { name, value ->
putCustomAttribute(name, value)
}
})
}
is PurchaseFinished -> {
answers.logPurchase(configure(PurchaseEvent()) { answers.logPurchase(configure(PurchaseEvent()) {
putItemName(event.productName) putItemName(event.productName)
putSuccess(event.resultCode == Activity.RESULT_OK)
if (!event.price.isNaN() && event.currency != null) { if (!event.price.isNaN() && event.currency != null) {
putCurrency(Currency.getInstance(event.currency) ?: Currency.getInstance(Locale.getDefault())) putCurrency(Currency.getInstance(event.currency) ?: Currency.getInstance(Locale.getDefault()))
putItemPrice(BigDecimal(event.price)) putItemPrice(BigDecimal(event.price))

View File

@ -6,8 +6,7 @@ import org.mariotaku.twidere.model.ParcelableMedia
* Created by mariotaku on 2017/1/7. * Created by mariotaku on 2017/1/7.
*/ */
fun parcelableMediaTypeString(@ParcelableMedia.Type type: Int): String { fun parcelableMediaTypeString(@ParcelableMedia.Type type: Int): String? {
if (type <= 0) return "none"
return when (type) { return when (type) {
ParcelableMedia.Type.IMAGE -> "image" ParcelableMedia.Type.IMAGE -> "image"
ParcelableMedia.Type.VIDEO -> "video" ParcelableMedia.Type.VIDEO -> "video"
@ -15,6 +14,6 @@ fun parcelableMediaTypeString(@ParcelableMedia.Type type: Int): String {
ParcelableMedia.Type.CARD_ANIMATED_GIF -> "gif" ParcelableMedia.Type.CARD_ANIMATED_GIF -> "gif"
ParcelableMedia.Type.EXTERNAL_PLAYER -> "external" ParcelableMedia.Type.EXTERNAL_PLAYER -> "external"
ParcelableMedia.Type.VARIABLE_TYPE -> "variable" ParcelableMedia.Type.VARIABLE_TYPE -> "variable"
else -> "unknown" else -> null
} }
} }

View File

@ -6,4 +6,4 @@ import org.mariotaku.twidere.model.ParcelableStatus
* Created by mariotaku on 2017/1/7. * Created by mariotaku on 2017/1/7.
*/ */
val ParcelableStatus.media_type: Int val ParcelableStatus.media_type: Int
get() = (media ?: quoted_media)?.firstOrNull()?.type ?: 0 get() = media?.firstOrNull()?.type ?: 0

View File

@ -6,6 +6,10 @@ import android.support.v7.app.AlertDialog
import android.view.View import android.view.View
import org.mariotaku.twidere.R import org.mariotaku.twidere.R
import org.mariotaku.twidere.constant.IntentConstants.EXTRA_REQUEST_CODE import org.mariotaku.twidere.constant.IntentConstants.EXTRA_REQUEST_CODE
import org.mariotaku.twidere.model.analyzer.PurchaseConfirm
import org.mariotaku.twidere.model.analyzer.PurchaseFinished
import org.mariotaku.twidere.model.analyzer.PurchaseIntroduction
import org.mariotaku.twidere.util.Analyzer
import org.mariotaku.twidere.util.premium.ExtraFeaturesService import org.mariotaku.twidere.util.premium.ExtraFeaturesService
/** /**
@ -36,6 +40,7 @@ class ExtraFeaturesIntroductionDialogFragment : BaseDialogFragment() {
} else { } else {
activity.startActivityForResult(purchaseIntent, requestCode) activity.startActivityForResult(purchaseIntent, requestCode)
} }
Analyzer.log(PurchaseConfirm(PurchaseFinished.NAME_EXTRA_FEATURES))
} }
builder.setNegativeButton(R.string.action_later) { dialog, which -> builder.setNegativeButton(R.string.action_later) { dialog, which ->
@ -55,6 +60,9 @@ class ExtraFeaturesIntroductionDialogFragment : BaseDialogFragment() {
View.GONE View.GONE
} }
} }
if (savedInstanceState == null) {
Analyzer.log(PurchaseIntroduction(PurchaseFinished.NAME_EXTRA_FEATURES, "introduction dialog"))
}
return dialog return dialog
} }
} }

View File

@ -437,7 +437,10 @@ class StatusFragment : BaseSupportFragment(), LoaderCallbacks<SingleResponse<Par
event.isHasTranslateFeature = false event.isHasTranslateFeature = false
} }
statusEvent = event statusEvent = event
Analyzer.log(StatusView(details?.type, status.media_type)) Analyzer.log(StatusView(details?.type, status.media_type).apply {
this.type = StatusView.getStatusType(status)
this.source = HtmlEscapeHelper.toPlainText(status.source)
})
} else if (readPosition != null) { } else if (readPosition != null) {
restoreReadPosition(readPosition) restoreReadPosition(readPosition)
} }

View File

@ -1,5 +1,6 @@
package org.mariotaku.twidere.fragment.filter package org.mariotaku.twidere.fragment.filter
import android.app.Activity
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.database.Cursor import android.database.Cursor
@ -28,7 +29,7 @@ import org.mariotaku.twidere.fragment.ExtraFeaturesIntroductionDialogFragment
import org.mariotaku.twidere.model.ParcelableUser import org.mariotaku.twidere.model.ParcelableUser
import org.mariotaku.twidere.model.UserKey import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.model.`FiltersData$UserItemCursorIndices` import org.mariotaku.twidere.model.`FiltersData$UserItemCursorIndices`
import org.mariotaku.twidere.model.analyzer.Purchase import org.mariotaku.twidere.model.analyzer.PurchaseFinished
import org.mariotaku.twidere.provider.TwidereDataStore import org.mariotaku.twidere.provider.TwidereDataStore
import org.mariotaku.twidere.util.Analyzer import org.mariotaku.twidere.util.Analyzer
import org.mariotaku.twidere.util.ContentValuesCreator import org.mariotaku.twidere.util.ContentValuesCreator
@ -91,7 +92,9 @@ class FilteredUsersFragment : BaseFiltersFragment() {
startActivityForResult(intent, REQUEST_ADD_USER_SELECT_ACCOUNT) startActivityForResult(intent, REQUEST_ADD_USER_SELECT_ACCOUNT)
} }
REQUEST_PURCHASE_EXTRA_FEATURES -> { REQUEST_PURCHASE_EXTRA_FEATURES -> {
Analyzer.log(Purchase.fromActivityResult(Purchase.NAME_EXTRA_FEATURES, resultCode, data)) if (resultCode == Activity.RESULT_OK) {
Analyzer.log(PurchaseFinished.create(PurchaseFinished.NAME_EXTRA_FEATURES, data))
}
} }
} }
} }

View File

@ -13,7 +13,9 @@ import org.mariotaku.twidere.R
import org.mariotaku.twidere.constant.RESULT_NOT_PURCHASED import org.mariotaku.twidere.constant.RESULT_NOT_PURCHASED
import org.mariotaku.twidere.constant.RESULT_SERVICE_UNAVAILABLE import org.mariotaku.twidere.constant.RESULT_SERVICE_UNAVAILABLE
import org.mariotaku.twidere.fragment.BaseSupportFragment import org.mariotaku.twidere.fragment.BaseSupportFragment
import org.mariotaku.twidere.model.analyzer.Purchase import org.mariotaku.twidere.model.analyzer.PurchaseConfirm
import org.mariotaku.twidere.model.analyzer.PurchaseFinished
import org.mariotaku.twidere.model.analyzer.PurchaseIntroduction
import org.mariotaku.twidere.util.Analyzer import org.mariotaku.twidere.util.Analyzer
import org.mariotaku.twidere.util.premium.ExtraFeaturesService import org.mariotaku.twidere.util.premium.ExtraFeaturesService
@ -33,6 +35,7 @@ class ExtraFeaturesIntroductionCardFragment : BaseSupportFragment() {
super.onActivityCreated(savedInstanceState) super.onActivityCreated(savedInstanceState)
extraFeaturesService = ExtraFeaturesService.newInstance(context) extraFeaturesService = ExtraFeaturesService.newInstance(context)
purchaseButton.setOnClickListener { purchaseButton.setOnClickListener {
Analyzer.log(PurchaseConfirm(PurchaseFinished.NAME_EXTRA_FEATURES))
startActivityForResult(extraFeaturesService.createPurchaseIntent(context), REQUEST_PURCHASE) startActivityForResult(extraFeaturesService.createPurchaseIntent(context), REQUEST_PURCHASE)
} }
val restorePurchaseIntent = extraFeaturesService.createRestorePurchaseIntent(context) val restorePurchaseIntent = extraFeaturesService.createRestorePurchaseIntent(context)
@ -47,14 +50,17 @@ class ExtraFeaturesIntroductionCardFragment : BaseSupportFragment() {
restorePurchaseButton.visibility = View.GONE restorePurchaseButton.visibility = View.GONE
restorePurchaseButton.setOnClickListener(null) restorePurchaseButton.setOnClickListener(null)
} }
if (savedInstanceState == null) {
Analyzer.log(PurchaseIntroduction(PurchaseFinished.NAME_EXTRA_FEATURES, "enhanced features dashboard"))
}
} }
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
when (requestCode) { when (requestCode) {
REQUEST_PURCHASE -> { REQUEST_PURCHASE -> {
Analyzer.log(Purchase.fromActivityResult(Purchase.NAME_EXTRA_FEATURES, resultCode, data))
when (resultCode) { when (resultCode) {
Activity.RESULT_OK -> { Activity.RESULT_OK -> {
Analyzer.log(PurchaseFinished.create(PurchaseFinished.NAME_EXTRA_FEATURES, data))
activity?.recreate() activity?.recreate()
} }
} }

View File

@ -0,0 +1,15 @@
package org.mariotaku.twidere.model.analyzer
import org.mariotaku.twidere.util.Analyzer
/**
* Created by mariotaku on 2017/1/7.
*/
data class PurchaseConfirm(val productName: String) : Analyzer.Event {
override val name: String = "Purchase Confirm"
override val accountType: String? = null
override fun forEachValues(action: (String, String?) -> Unit) {
action("Product Name", productName)
}
}

View File

@ -9,19 +9,12 @@ import org.mariotaku.twidere.util.Analyzer
* Created by mariotaku on 2017/1/7. * Created by mariotaku on 2017/1/7.
*/ */
data class Purchase(val productName: String) : Analyzer.Event { data class PurchaseFinished(val productName: String) : Analyzer.Event {
override val name: String = "Purchase" override val name: String = "Purchase Finished"
override var accountType: String? = null override var accountType: String? = null
var resultCode: Int = Activity.RESULT_OK
var price: Double = Double.NaN var price: Double = Double.NaN
var currency: String? = null var currency: String? = null
override fun forEachValues(action: (String, String?) -> Unit) {
if (resultCode != Activity.RESULT_OK) {
action("Fail reason", getFailReason(resultCode))
}
}
companion object { companion object {
const val NAME_EXTRA_FEATURES = "Enhanced Features" const val NAME_EXTRA_FEATURES = "Enhanced Features"
@ -35,9 +28,8 @@ data class Purchase(val productName: String) : Analyzer.Event {
} }
} }
fun fromActivityResult(name: String, resultCode: Int, data: Intent?): Purchase { fun create(name: String, data: Intent?): PurchaseFinished {
val result = Purchase(name) val result = PurchaseFinished(name)
result.resultCode = resultCode
if (data != null) { if (data != null) {
result.price = data.getDoubleExtra(EXTRA_PRICE, Double.NaN) result.price = data.getDoubleExtra(EXTRA_PRICE, Double.NaN)
result.currency = data.getStringExtra(EXTRA_CURRENCY) result.currency = data.getStringExtra(EXTRA_CURRENCY)

View File

@ -0,0 +1,16 @@
package org.mariotaku.twidere.model.analyzer
import org.mariotaku.twidere.util.Analyzer
/**
* Created by mariotaku on 2017/1/7.
*/
data class PurchaseIntroduction(val productName: String, val source: String) : Analyzer.Event {
override val name: String = "Purchase Introduction"
override val accountType: String? = null
override fun forEachValues(action: (String, String?) -> Unit) {
action("Product Name", productName)
action("Source", source)
}
}

View File

@ -3,6 +3,7 @@ package org.mariotaku.twidere.model.analyzer
import org.mariotaku.twidere.annotation.AccountType import org.mariotaku.twidere.annotation.AccountType
import org.mariotaku.twidere.extension.model.parcelableMediaTypeString import org.mariotaku.twidere.extension.model.parcelableMediaTypeString
import org.mariotaku.twidere.model.ParcelableMedia import org.mariotaku.twidere.model.ParcelableMedia
import org.mariotaku.twidere.model.ParcelableStatus
import org.mariotaku.twidere.util.Analyzer import org.mariotaku.twidere.util.Analyzer
/** /**
@ -15,8 +16,31 @@ data class StatusView(
) : Analyzer.Event { ) : Analyzer.Event {
override val name: String = "Status View" override val name: String = "Status View"
var type: String? = null
var source: String? = null
override fun forEachValues(action: (String, String?) -> Unit) { override fun forEachValues(action: (String, String?) -> Unit) {
action("Media Type", parcelableMediaTypeString(mediaType)) val mediaType = parcelableMediaTypeString(mediaType)
if (mediaType != null) {
action("Media Type", mediaType)
}
if (type != null) {
action("Type", type)
}
if (source != null) {
action("Source", source)
}
}
companion object {
@JvmStatic
fun getStatusType(status: ParcelableStatus): String {
if (status.is_retweet) {
return "retweet"
} else if (status.is_quote) {
return "quote"
}
return "tweet"
}
} }
} }