2
0
mirror of https://github.com/fork-maintainers/iceraven-browser synced 2024-11-11 13:11:01 +00:00

Allow play store in app review to be shown to users

This commit is contained in:
Elise Richards 2020-08-24 14:34:27 -05:00 committed by Jeff Boek
parent 4b997c1334
commit e96eb25682
5 changed files with 91 additions and 0 deletions

View File

@ -439,6 +439,9 @@ dependencies {
implementation Deps.google_ads_id // Required for the Google Advertising ID implementation Deps.google_ads_id // Required for the Google Advertising ID
implementation Deps.google_play_store // Required for in-app reviews
implementation Deps.google_play_core_ktx // Required for in-app reviews
androidTestImplementation Deps.uiautomator androidTestImplementation Deps.uiautomator
// Removed pending AndroidX fixes // Removed pending AndroidX fixes
androidTestImplementation "tools.fastlane:screengrab:2.0.0" androidTestImplementation "tools.fastlane:screengrab:2.0.0"

View File

@ -42,6 +42,9 @@ import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView.SCROLL_STATE_IDLE import androidx.recyclerview.widget.RecyclerView.SCROLL_STATE_IDLE
import com.google.android.material.snackbar.Snackbar import com.google.android.material.snackbar.Snackbar
import com.google.android.play.core.ktx.launchReview
import com.google.android.play.core.ktx.requestReview
import com.google.android.play.core.review.ReviewManagerFactory
import kotlinx.android.synthetic.main.fragment_home.* import kotlinx.android.synthetic.main.fragment_home.*
import kotlinx.android.synthetic.main.fragment_home.view.* import kotlinx.android.synthetic.main.fragment_home.view.*
import kotlinx.android.synthetic.main.no_collections_message.view.* import kotlinx.android.synthetic.main.no_collections_message.view.*
@ -567,10 +570,26 @@ class HomeFragment : Fragment() {
recommendPrivateBrowsingShortcut() recommendPrivateBrowsingShortcut()
} }
// In-app review prompt
requireContext().settings().incrementNumTimesOpenedAfterInstall()
handleInAppReviewPrompt()
// We only want this observer live just before we navigate away to the collection creation screen // We only want this observer live just before we navigate away to the collection creation screen
requireComponents.core.tabCollectionStorage.unregister(collectionStorageObserver) requireComponents.core.tabCollectionStorage.unregister(collectionStorageObserver)
} }
private fun handleInAppReviewPrompt() {
if (requireContext().settings().shouldShowUserFeedbackPrompt) {
lifecycleScope.launch {
val manager = ReviewManagerFactory.create(requireContext())
val reviewInfo = manager.requestReview()
manager.launchReview(requireActivity(), reviewInfo)
requireContext().settings().incrementNumTimesFeedbackPromptShown()
}
}
}
private fun dispatchModeChanges(mode: Mode) { private fun dispatchModeChanges(mode: Mode) {
if (mode != Mode.fromBrowsingMode(browsingModeManager.mode)) { if (mode != Mode.fromBrowsingMode(browsingModeManager.mode)) {
homeFragmentStore.dispatch(HomeFragmentAction.ModeChange(mode)) homeFragmentStore.dispatch(HomeFragmentAction.ModeChange(mode))

View File

@ -12,6 +12,7 @@ import android.content.SharedPreferences
import android.content.pm.ShortcutManager import android.content.pm.ShortcutManager
import android.os.Build import android.os.Build
import android.view.accessibility.AccessibilityManager import android.view.accessibility.AccessibilityManager
import androidx.annotation.RequiresApi
import androidx.annotation.VisibleForTesting import androidx.annotation.VisibleForTesting
import androidx.annotation.VisibleForTesting.PRIVATE import androidx.annotation.VisibleForTesting.PRIVATE
import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.LifecycleOwner
@ -39,6 +40,7 @@ import org.mozilla.fenix.settings.logins.SavedLoginsSortingStrategyMenu
import org.mozilla.fenix.settings.logins.SortingStrategy import org.mozilla.fenix.settings.logins.SortingStrategy
import org.mozilla.fenix.settings.registerOnSharedPreferenceChangeListener import org.mozilla.fenix.settings.registerOnSharedPreferenceChangeListener
import java.security.InvalidParameterException import java.security.InvalidParameterException
import java.time.LocalDate
private const val AUTOPLAY_USER_SETTING = "AUTOPLAY_USER_SETTING" private const val AUTOPLAY_USER_SETTING = "AUTOPLAY_USER_SETTING"
@ -63,6 +65,7 @@ class Settings(private val appContext: Context) : PreferencesHolder {
private const val ALLOWED_INT = 2 private const val ALLOWED_INT = 2
private const val CFR_COUNT_CONDITION_FOCUS_INSTALLED = 1 private const val CFR_COUNT_CONDITION_FOCUS_INSTALLED = 1
private const val CFR_COUNT_CONDITION_FOCUS_NOT_INSTALLED = 3 private const val CFR_COUNT_CONDITION_FOCUS_NOT_INSTALLED = 3
private const val MIN_DAYS_SINCE_FEEDBACK_PROMPT = 120
private fun Action.toInt() = when (this) { private fun Action.toInt() = when (this) {
Action.BLOCKED -> BLOCKED_INT Action.BLOCKED -> BLOCKED_INT
@ -792,6 +795,62 @@ class Settings(private val appContext: Context) : PreferencesHolder {
0 0
) )
private val numTimesFeedbackPromptShown: Int
get() = preferences.getInt(
appContext.getPreferenceKey(R.string.pref_key_feedback_prompt_shown),
0
)
fun incrementNumTimesFeedbackPromptShown() {
preferences.edit().putInt(
appContext.getPreferenceKey(R.string.pref_key_feedback_prompt_shown),
numTimesFeedbackPromptShown + 1
).apply()
}
private val numTimesOpenedAfterInstall: Int
get() = preferences.getInt(
appContext.getPreferenceKey(R.string.pref_key_times_opened_after_install),
0
)
fun incrementNumTimesOpenedAfterInstall() {
preferences.edit().putInt(
appContext.getPreferenceKey(R.string.pref_key_times_opened_after_install),
numTimesOpenedAfterInstall + 1
).apply()
}
private val timeWhenPromptWasLastShown: Int
get() = preferences.getInt(
appContext.getPreferenceKey(R.string.pref_key_time_prompt_shown),
0
)
@RequiresApi(Build.VERSION_CODES.O)
fun incrementTimeWhenPromptWasLastShown() {
preferences.edit().putInt(
appContext.getPreferenceKey(R.string.pref_key_time_prompt_shown),
LocalDate.now().dayOfYear
).apply()
}
/*
* User feedback prompt is shown when Firefox is set as the default browser and after the
* 5th time the user opened the app. This prompt should only be shown once every four months.
*/
@RequiresApi(Build.VERSION_CODES.O)
val shouldShowUserFeedbackPrompt: Boolean =
numTimesOpenedAfterInstall >= 5
&& isDefaultBrowser()
&& (hasBeenFourMonthsSince(timeWhenPromptWasLastShown))
@RequiresApi(Build.VERSION_CODES.O)
private fun hasBeenFourMonthsSince(timeWhenPromptWasLastShown: Int): Boolean {
val numDays = LocalDate.now().dayOfYear - timeWhenPromptWasLastShown
return numDays >= MIN_DAYS_SINCE_FEEDBACK_PROMPT
}
val showPrivateModeContextualFeatureRecommender: Boolean val showPrivateModeContextualFeatureRecommender: Boolean
get() { get() {
val focusInstalled = MozillaProductDetector val focusInstalled = MozillaProductDetector

View File

@ -58,6 +58,9 @@
<string name="pref_key_open_in_app_opened" translatable="false">pref_key_open_in_app_opened</string> <string name="pref_key_open_in_app_opened" translatable="false">pref_key_open_in_app_opened</string>
<string name="pref_key_install_pwa_opened" translatable="false">pref_key_install_pwa_opened</string> <string name="pref_key_install_pwa_opened" translatable="false">pref_key_install_pwa_opened</string>
<string name="pref_key_install_pwa_visits" translatable="false">pref_key_install_pwa_visits</string> <string name="pref_key_install_pwa_visits" translatable="false">pref_key_install_pwa_visits</string>
<string name="pref_key_feedback_prompt_shown" translatable="false">pref_key_feedback_prompt_shown</string>
<string name="pref_key_times_opened_after_install" translatable="false">pref_key_times_opened_after_install</string>
<string name="pref_key_time_prompt_shown" translatable="false">pref_key_time_prompt_shown</string>
<!-- Data Choices --> <!-- Data Choices -->
<string name="pref_key_telemetry" translatable="false">pref_key_telemetry</string> <string name="pref_key_telemetry" translatable="false">pref_key_telemetry</string>

View File

@ -42,6 +42,9 @@ object Versions {
const val google_ads_id_version = "16.0.0" const val google_ads_id_version = "16.0.0"
const val google_play_store_version = "1.8.0"
const val google_play_core_ktx_version = "1.8.1"
const val airbnb_lottie = "3.4.0" const val airbnb_lottie = "3.4.0"
} }
@ -209,6 +212,10 @@ object Deps {
const val google_ads_id = "com.google.android.gms:play-services-ads-identifier:${Versions.google_ads_id_version}" const val google_ads_id = "com.google.android.gms:play-services-ads-identifier:${Versions.google_ads_id_version}"
// Required for in-app reviews
const val google_play_store = "com.google.android.play:core:${Versions.google_play_store_version}"
const val google_play_core_ktx = "com.google.android.play:core-ktx:${Versions.google_play_core_ktx_version}"
const val lottie = "com.airbnb.android:lottie:${Versions.airbnb_lottie}" const val lottie = "com.airbnb.android:lottie:${Versions.airbnb_lottie}"
const val detektApi = "io.gitlab.arturbosch.detekt:detekt-api:${Versions.detekt}" const val detektApi = "io.gitlab.arturbosch.detekt:detekt-api:${Versions.detekt}"