diff --git a/app/lint.xml b/app/lint.xml
index cf2226aea..aa99dd31f 100644
--- a/app/lint.xml
+++ b/app/lint.xml
@@ -7,6 +7,8 @@
+
+
diff --git a/app/src/main/java/org/mozilla/fenix/components/ReviewPromptController.kt b/app/src/main/java/org/mozilla/fenix/components/ReviewPromptController.kt
index 36109b893..a3cbb91ce 100644
--- a/app/src/main/java/org/mozilla/fenix/components/ReviewPromptController.kt
+++ b/app/src/main/java/org/mozilla/fenix/components/ReviewPromptController.kt
@@ -26,7 +26,7 @@ interface ReviewSettings {
*/
class FenixReviewSettings(
val settings: Settings
-): ReviewSettings {
+) : ReviewSettings {
override var numberOfAppLaunches: Int
get() = settings.numberOfAppLaunches
set(value) { settings.numberOfAppLaunches = value }
@@ -43,14 +43,16 @@ class FenixReviewSettings(
class ReviewPromptController(
private val context: Context,
private val reviewSettings: ReviewSettings,
- private val timeNowInMillis: () -> Long = { System.currentTimeMillis() }
+ private val timeNowInMillis: () -> Long = { System.currentTimeMillis() },
+ private val tryPromptReview: suspend (Activity) -> Unit = {
+ val manager = ReviewManagerFactory.create(context)
+ val reviewInfo = manager.requestReview()
+ manager.launchReview(it, reviewInfo)
+ }
) {
suspend fun promptReview(activity: Activity) {
if (shouldShowPrompt()) {
- val manager = ReviewManagerFactory.create(context)
- val reviewInfo = manager.requestReview()
- manager.launchReview(activity, reviewInfo)
-
+ tryPromptReview(activity)
reviewSettings.lastReviewPromptTimeInMillis = timeNowInMillis()
}
}
@@ -63,14 +65,18 @@ class ReviewPromptController(
fun shouldShowPrompt(): Boolean {
if (!reviewSettings.isDefaultBrowser) { return false }
- val hasOpenedFiveTimes = reviewSettings.numberOfAppLaunches >= 5
- val apprxFourMonthsAgo = timeNowInMillis() - (APPRX_MONTH_IN_MILLIS * 4)
- val hasNotBeenPromptedLastFourMonths = reviewSettings.lastReviewPromptTimeInMillis <= apprxFourMonthsAgo
+ val hasOpenedFiveTimes = reviewSettings.numberOfAppLaunches >= NUMBER_OF_LAUNCHES_REQUIRED
+ val now = timeNowInMillis()
+ val apprxFourMonthsAgo = now - (APPRX_MONTH_IN_MILLIS * NUMBER_OF_MONTHS_TO_PASS)
+ val lastPrompt = reviewSettings.lastReviewPromptTimeInMillis
+ val hasNotBeenPromptedLastFourMonths = lastPrompt == 0L || lastPrompt <= apprxFourMonthsAgo
return hasOpenedFiveTimes && hasNotBeenPromptedLastFourMonths
}
companion object {
private const val APPRX_MONTH_IN_MILLIS: Long = 1000L * 60L * 60L * 24L * 30L
+ private const val NUMBER_OF_LAUNCHES_REQUIRED = 5
+ private const val NUMBER_OF_MONTHS_TO_PASS = 4
}
-}
\ No newline at end of file
+}
diff --git a/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt b/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt
index cac266fe2..98e16c9c2 100644
--- a/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt
+++ b/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt
@@ -42,9 +42,6 @@ import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView.SCROLL_STATE_IDLE
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.view.*
import kotlinx.android.synthetic.main.no_collections_message.view.*
diff --git a/app/src/main/java/org/mozilla/fenix/utils/Settings.kt b/app/src/main/java/org/mozilla/fenix/utils/Settings.kt
index c953fdd50..b4f096fdc 100644
--- a/app/src/main/java/org/mozilla/fenix/utils/Settings.kt
+++ b/app/src/main/java/org/mozilla/fenix/utils/Settings.kt
@@ -12,7 +12,6 @@ import android.content.SharedPreferences
import android.content.pm.ShortcutManager
import android.os.Build
import android.view.accessibility.AccessibilityManager
-import androidx.annotation.RequiresApi
import androidx.annotation.VisibleForTesting
import androidx.annotation.VisibleForTesting.PRIVATE
import androidx.lifecycle.LifecycleOwner
@@ -40,7 +39,6 @@ import org.mozilla.fenix.settings.logins.SavedLoginsSortingStrategyMenu
import org.mozilla.fenix.settings.logins.SortingStrategy
import org.mozilla.fenix.settings.registerOnSharedPreferenceChangeListener
import java.security.InvalidParameterException
-import java.time.LocalDate
private const val AUTOPLAY_USER_SETTING = "AUTOPLAY_USER_SETTING"
diff --git a/app/src/test/java/org/mozilla/fenix/components/ReviewPromptControllerTest.kt b/app/src/test/java/org/mozilla/fenix/components/ReviewPromptControllerTest.kt
new file mode 100644
index 000000000..0a9fdbbfc
--- /dev/null
+++ b/app/src/test/java/org/mozilla/fenix/components/ReviewPromptControllerTest.kt
@@ -0,0 +1,144 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package org.mozilla.fenix.components
+
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.runBlockingTest
+import mozilla.components.support.test.robolectric.testContext
+import org.junit.Test
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertTrue
+import org.junit.Assert.assertFalse
+import org.junit.runner.RunWith
+import org.mozilla.fenix.HomeActivity
+import org.mozilla.fenix.helpers.FenixRobolectricTestRunner
+
+class TestReviewSettings(
+ override var numberOfAppLaunches: Int = 0,
+ var isDefault: Boolean = false,
+ override var lastReviewPromptTimeInMillis: Long = 0
+) : ReviewSettings {
+ override val isDefaultBrowser: Boolean
+ get() = isDefault
+}
+
+@ExperimentalCoroutinesApi
+@RunWith(FenixRobolectricTestRunner::class)
+class ReviewPromptControllerTest {
+ @Test
+ fun promptReviewDoesNotSetMillis() = runBlockingTest {
+ var promptWasCalled = false
+ val settings = TestReviewSettings(
+ numberOfAppLaunches = 5,
+ isDefault = false,
+ lastReviewPromptTimeInMillis = 0L
+ )
+
+ val controller = ReviewPromptController(
+ testContext,
+ settings,
+ { 100L },
+ { promptWasCalled = true }
+ )
+
+ controller.promptReview(HomeActivity())
+ assertEquals(settings.lastReviewPromptTimeInMillis, 0L)
+ assertFalse(promptWasCalled)
+ }
+
+ @Test
+ fun promptReviewSetsMillisIfSuccessful() = runBlockingTest {
+ var promptWasCalled = false
+ val settings = TestReviewSettings(
+ numberOfAppLaunches = 5,
+ isDefault = true,
+ lastReviewPromptTimeInMillis = 0L
+ )
+
+ val controller = ReviewPromptController(
+ testContext,
+ settings,
+ { 100L },
+ { promptWasCalled = true }
+ )
+
+ controller.promptReview(HomeActivity())
+ assertEquals(100L, settings.lastReviewPromptTimeInMillis)
+ assertTrue(promptWasCalled)
+ }
+
+ @Test
+ fun trackApplicationLaunch() {
+ val settings = TestReviewSettings(
+ numberOfAppLaunches = 4,
+ isDefault = true,
+ lastReviewPromptTimeInMillis = 0L
+ )
+
+ val controller = ReviewPromptController(
+ testContext,
+ settings,
+ { 100L }
+ )
+
+ assertEquals(4, settings.numberOfAppLaunches)
+ controller.trackApplicationLaunch()
+ assertEquals(5, settings.numberOfAppLaunches)
+ }
+
+ @Test
+ fun shouldShowPrompt() {
+ val settings = TestReviewSettings(
+ numberOfAppLaunches = 5,
+ isDefault = true,
+ lastReviewPromptTimeInMillis = 0L
+ )
+
+ val controller = ReviewPromptController(
+ testContext,
+ settings,
+ { 1598416882805L }
+ )
+
+ // Test first success criteria
+ assertTrue(controller.shouldShowPrompt())
+
+ // Test with last prompt approx 4 months earlier
+ settings.apply {
+ numberOfAppLaunches = 5
+ isDefault = true
+ lastReviewPromptTimeInMillis = 1588048882804L
+ }
+
+ assertTrue(controller.shouldShowPrompt())
+
+ // Test without being the default browser
+ settings.apply {
+ numberOfAppLaunches = 5
+ isDefault = false
+ lastReviewPromptTimeInMillis = 1595824882805L
+ }
+
+ assertFalse(controller.shouldShowPrompt())
+
+ // Test with number of app launches < 5
+ settings.apply {
+ numberOfAppLaunches = 4
+ isDefault = true
+ lastReviewPromptTimeInMillis = 0L
+ }
+
+ assertFalse(controller.shouldShowPrompt())
+
+ // Test with last prompt less than 4 months ago
+ settings.apply {
+ numberOfAppLaunches = 5
+ isDefault = true
+ lastReviewPromptTimeInMillis = 1595824882905L
+ }
+
+ assertFalse(controller.shouldShowPrompt())
+ }
+}