Run ktlintFormat to adapt to latest formatting rules.

upstream-sync
Sebastian Kaspari 3 years ago committed by mergify[bot]
parent 94f9c23721
commit 971b419d77

@ -79,9 +79,11 @@ class BaselinePingTest {
@JvmStatic
@OptIn(DelicateCoroutinesApi::class) // GlobalScope usage
fun setupOnce() {
val httpClient = ConceptFetchHttpUploader(lazy {
GeckoViewFetchClient(ApplicationProvider.getApplicationContext())
})
val httpClient = ConceptFetchHttpUploader(
lazy {
GeckoViewFetchClient(ApplicationProvider.getApplicationContext())
}
)
// Fenix does not initialize the Glean SDK in tests/debug builds, but this test
// requires Glean to be initialized so we need to do it manually. Additionally,
@ -151,8 +153,11 @@ class BaselinePingTest {
// sending the ping that was submitted on background. This can go away once bug 1634375
// is fixed.
device.pressRecentApps()
device.findObject(UiSelector().descriptionContains(
ApplicationProvider.getApplicationContext<Context>().getString(R.string.app_name)))
device.findObject(
UiSelector().descriptionContains(
ApplicationProvider.getApplicationContext<Context>().getString(R.string.app_name)
)
)
.click()
// Validate the received data.

@ -83,7 +83,7 @@ object TestHelper {
fun getPermissionAllowID(): String {
return when
(Build.VERSION.SDK_INT > Build.VERSION_CODES.P) {
(Build.VERSION.SDK_INT > Build.VERSION_CODES.P) {
true -> "com.android.permissioncontroller"
false -> "com.android.packageinstaller"
}

@ -58,7 +58,7 @@ private val failureMsgRecyclerViewConstraintLayoutChildren = getErrorMessage(
private val failureMsgNumberOfInflation = getErrorMessage(
shortName = "Number of inflation on start up doesn't match expected count",
implications = "The number of inflation can negatively impact start up time. Having more inflations" +
"will most likely mean we're adding extra work on the UI thread."
"will most likely mean we're adding extra work on the UI thread."
)
/**
* A performance test to limit the number of StrictMode suppressions and number of runBlocking used

@ -83,14 +83,14 @@ class MenuScreenShotTest : ScreenshotTest() {
}.openLanguageSubMenu {
Screengrab.screenshot("SettingsSubMenuAccessibilityRobot_settings-language")
}.goBack {
// From about here we need to scroll up to ensure all settings options are visible.
// From about here we need to scroll up to ensure all settings options are visible.
}.openSetDefaultBrowserSubMenu {
Screengrab.screenshot("SettingsSubMenuDefaultBrowserRobot_settings-default-browser")
}.goBack {
// Disabled for Pixel 2
// }.openEnhancedTrackingProtectionSubMenu {
// Screengrab.screenshot("settings-enhanced-tp")
// }.goBack {
// Disabled for Pixel 2
// }.openEnhancedTrackingProtectionSubMenu {
// Screengrab.screenshot("settings-enhanced-tp")
// }.goBack {
}.openLoginsAndPasswordSubMenu {
Screengrab.screenshot("SettingsSubMenuLoginsAndPasswords-settings-logins-passwords")
}.goBack {
@ -176,7 +176,7 @@ class MenuScreenShotTest : ScreenshotTest() {
@Test
fun saveLoginPromptTest() {
val saveLoginTest =
TestAssetHelper.getSaveLoginAsset(mockWebServer)
TestAssetHelper.getSaveLoginAsset(mockWebServer)
navigationToolbar {
}.enterURLAndEnterToBrowser(saveLoginTest.url) {
verifySaveLoginPromptIsShownNotSave()

@ -173,9 +173,11 @@ class SyncIntegrationTest {
// Useful functions for the tests
fun typeEmail() {
val emailInput = mDevice.findObject(UiSelector()
val emailInput = mDevice.findObject(
UiSelector()
.instance(0)
.className(EditText::class.java))
.className(EditText::class.java)
)
emailInput.waitForExists(TestAssetHelper.waitingTime)
val emailAddress = javaClass.classLoader!!.getResource("email.txt").readText()
@ -188,9 +190,11 @@ class SyncIntegrationTest {
}
fun typePassword() {
val passwordInput = mDevice.findObject(UiSelector()
val passwordInput = mDevice.findObject(
UiSelector()
.instance(0)
.className(EditText::class.java))
.className(EditText::class.java)
)
val passwordValue = javaClass.classLoader!!.getResource("password.txt").readText()
passwordInput.setText(passwordValue)

@ -96,7 +96,7 @@ class SettingsAddonsTest {
acceptInstallAddon()
verifyDownloadAddonPrompt(addonName, activityTestRule)
}
}
}
// Opens the addons settings menu, installs an addon, then uninstalls

@ -44,19 +44,19 @@ private fun deviceName() = Espresso.onView(CoreMatchers.allOf(ViewMatchers.withT
private fun disconnectButton() = Espresso.onView(CoreMatchers.allOf(ViewMatchers.withId(R.id.signOutDisconnect)))
private fun assertBookmarksCheckbox() = bookmarksCheckbox().check(
ViewAssertions.matches(
ViewMatchers.withEffectiveVisibility(
ViewMatchers.Visibility.VISIBLE
)
ViewAssertions.matches(
ViewMatchers.withEffectiveVisibility(
ViewMatchers.Visibility.VISIBLE
)
)
)
private fun assertHistoryCheckbox() = historyCheckbox().check(
ViewAssertions.matches(
ViewMatchers.withEffectiveVisibility(
ViewMatchers.Visibility.VISIBLE
)
ViewAssertions.matches(
ViewMatchers.withEffectiveVisibility(
ViewMatchers.Visibility.VISIBLE
)
)
)
private fun assertSignOutButton() = signOutButton().check(ViewAssertions.matches(ViewMatchers.withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))

@ -91,8 +91,12 @@ fun addToHomeScreen(interact: AddToHomeScreenRobot.() -> Unit): AddToHomeScreenR
private fun shortcutNameField() = onView(withId(R.id.shortcut_text))
private fun assertShortcutNameField(expectedText: String) {
onView(allOf(withId(R.id.shortcut_text),
withText(expectedText)))
onView(
allOf(
withId(R.id.shortcut_text),
withText(expectedText)
)
)
.check(matches(isCompletelyDisplayed()))
}

@ -105,8 +105,10 @@ class BookmarksRobot {
fun verifySelectDefaultFolderSnackBarText() = assertSnackBarText("Cant edit default folders")
fun verifyCurrentFolderTitle(title: String) {
mDevice.findObject(UiSelector().resourceId("$packageName:id/navigationToolbar")
.textContains(title))
mDevice.findObject(
UiSelector().resourceId("$packageName:id/navigationToolbar")
.textContains(title)
)
.waitForExists(waitingTime)
onView(
@ -119,8 +121,10 @@ class BookmarksRobot {
}
fun waitForBookmarksFolderContentToExist(parentFolderName: String, childFolderName: String) {
mDevice.findObject(UiSelector().resourceId("$packageName:id/navigationToolbar")
.textContains(parentFolderName))
mDevice.findObject(
UiSelector().resourceId("$packageName:id/navigationToolbar")
.textContains(parentFolderName)
)
.waitForExists(waitingTime)
mDevice.waitNotNull(Until.findObject(By.text(childFolderName)), waitingTime)

@ -509,8 +509,10 @@ class BrowserRobot {
fun openTabDrawer(interact: TabDrawerRobot.() -> Unit): TabDrawerRobot.Transition {
mDevice.waitForIdle(waitingTime)
tabsCounter().click()
mDevice.waitNotNull(Until.findObject(By.res("$packageName:id/tab_layout")),
waitingTime)
mDevice.waitNotNull(
Until.findObject(By.res("$packageName:id/tab_layout")),
waitingTime
)
TabDrawerRobot().interact()
return TabDrawerRobot.Transition()

@ -58,8 +58,10 @@ class DownloadRobot {
}
fun waitForDownloadsListToExist() =
assertTrue(mDevice.findObject(UiSelector().resourceId("$packageName:id/download_list"))
.waitForExists(waitingTime))
assertTrue(
mDevice.findObject(UiSelector().resourceId("$packageName:id/download_list"))
.waitForExists(waitingTime)
)
class Transition {
fun clickDownload(interact: DownloadRobot.() -> Unit): Transition {

@ -179,8 +179,8 @@ private fun assertBasicLevelTrackingContentBlocked() {
withText(
containsString(
"social-track-digest256.dummytracker.org\n" +
"ads-track-digest256.dummytracker.org\n" +
"analytics-track-digest256.dummytracker.org"
"ads-track-digest256.dummytracker.org\n" +
"analytics-track-digest256.dummytracker.org"
)
)
)

@ -94,7 +94,7 @@ class HistoryRobot {
}
fun openThreeDotMenu(interact: ThreeDotMenuHistoryItemRobot.() -> Unit):
ThreeDotMenuHistoryItemRobot.Transition {
ThreeDotMenuHistoryItemRobot.Transition {
threeDotMenu().click()

@ -61,9 +61,9 @@ import org.mozilla.fenix.ui.util.STRING_ONBOARDING_TRACKING_PROTECTION_HEADER
class HomeScreenRobot {
val privateSessionMessage =
"$appName clears your search and browsing history from private tabs when you close them" +
" or quit the app. While this doesnt make you anonymous to websites or your internet" +
" service provider, it makes it easier to keep what you do online private from anyone" +
" else who uses this device."
" or quit the app. While this doesnt make you anonymous to websites or your internet" +
" service provider, it makes it easier to keep what you do online private from anyone" +
" else who uses this device."
fun verifyNavigationToolbar() = assertNavigationToolbar()
fun verifyFocusedNavigationToolbar() = assertFocusedNavigationToolbar()
@ -207,7 +207,7 @@ class HomeScreenRobot {
}
fun triggerPrivateBrowsingShortcutPrompt(interact: AddToHomeScreenRobot.() -> Unit): AddToHomeScreenRobot.Transition {
// Loop to press the PB icon for 5 times to display the Add the Private Browsing Shortcut CFR
// Loop to press the PB icon for 5 times to display the Add the Private Browsing Shortcut CFR
for (i in 1..5) {
mDevice.findObject(UiSelector().resourceId("$packageName:id/privateBrowsingButton"))
.waitForExists(
@ -356,7 +356,7 @@ private fun assertFocusedNavigationToolbar() =
private fun assertHomeScreen() {
mDevice.findObject(UiSelector().resourceId("$packageName:id/homeLayout")).waitForExists(waitingTime)
onView(ViewMatchers.withResourceName("homeLayout"))
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
}
private fun assertHomeMenu() = onView(ViewMatchers.withResourceName("menuButton"))
@ -383,7 +383,8 @@ private fun assertCollectionsHeader() =
private fun assertNoCollectionsText() =
onView(
withText(
containsString("Collect the things that matter to you.\n" +
containsString(
"Collect the things that matter to you.\n" +
"Group together similar searches, sites, and tabs for quick access later."
)
)

@ -58,7 +58,8 @@ class LibrarySubMenusMultipleSelectionToolbarRobot {
mDevice.waitNotNull(
Until.findObject(
By.text("ALL ACTIONS")
), waitingTime
),
waitingTime
)
}
@ -68,7 +69,8 @@ class LibrarySubMenusMultipleSelectionToolbarRobot {
mDevice.waitNotNull(
Until.findObject(
By.text("ALL ACTIONS")
), waitingTime
),
waitingTime
)
}

@ -70,8 +70,10 @@ class NavigationToolbarRobot {
fun typeSearchTerm(searchTerm: String) = awesomeBar().perform(typeText(searchTerm))
fun toggleReaderView() {
mDevice.findObject(UiSelector()
.resourceId("$packageName:id/mozac_browser_toolbar_page_actions"))
mDevice.findObject(
UiSelector()
.resourceId("$packageName:id/mozac_browser_toolbar_page_actions")
)
.waitForExists(waitingTime)
readerViewToggle().click()
@ -133,7 +135,8 @@ class NavigationToolbarRobot {
when (etpEnabled) {
true ->
try {
assertTrue("Onboarding message not displayed",
assertTrue(
"Onboarding message not displayed",
onboardingDisplayed
)
} catch (e: AssertionError) {
@ -184,8 +187,10 @@ class NavigationToolbarRobot {
fun openTabTray(interact: TabDrawerRobot.() -> Unit): TabDrawerRobot.Transition {
mDevice.waitForIdle(waitingTime)
tabTrayButton().click()
mDevice.waitNotNull(Until.findObject(By.res("$packageName:id/tab_layout")),
waitingTime)
mDevice.waitNotNull(
Until.findObject(By.res("$packageName:id/tab_layout")),
waitingTime
)
TabDrawerRobot().interact()
return TabDrawerRobot.Transition()
@ -251,7 +256,8 @@ class NavigationToolbarRobot {
RecyclerViewActions.actionOnItem<RecyclerView.ViewHolder>(
hasDescendant(
withText("Close tab")
), ViewActions.click()
),
ViewActions.click()
)
)
@ -267,7 +273,8 @@ class NavigationToolbarRobot {
RecyclerViewActions.actionOnItem<RecyclerView.ViewHolder>(
hasDescendant(
withText("New tab")
), ViewActions.click()
),
ViewActions.click()
)
)
@ -283,7 +290,8 @@ class NavigationToolbarRobot {
RecyclerViewActions.actionOnItem<RecyclerView.ViewHolder>(
hasDescendant(
withText("New private tab")
), ViewActions.click()
),
ViewActions.click()
)
)
@ -352,8 +360,10 @@ private fun readerViewToggle() =
onView(withParent(withId(R.id.mozac_browser_toolbar_page_actions)))
private fun assertReaderViewDetected(visible: Boolean) {
mDevice.findObject(UiSelector()
.description("Reader view"))
mDevice.findObject(
UiSelector()
.description("Reader view")
)
.waitForExists(waitingTime)
onView(
@ -368,8 +378,10 @@ private fun assertReaderViewDetected(visible: Boolean) {
}
private fun assertCloseReaderViewDetected(visible: Boolean) {
mDevice.findObject(UiSelector()
.description("Close reader view"))
mDevice.findObject(
UiSelector()
.description("Close reader view")
)
.waitForExists(waitingTime)
onView(

@ -55,9 +55,9 @@ class ReaderViewRobot {
val prefs = InstrumentationRegistry.getInstrumentation()
.targetContext.getSharedPreferences(
"mozac_feature_reader_view",
Context.MODE_PRIVATE
)
"mozac_feature_reader_view",
Context.MODE_PRIVATE
)
assertEquals(fontType, prefs.getString(fontTypeKey, ""))
}
@ -67,9 +67,9 @@ class ReaderViewRobot {
val prefs = InstrumentationRegistry.getInstrumentation()
.targetContext.getSharedPreferences(
"mozac_feature_reader_view",
Context.MODE_PRIVATE
)
"mozac_feature_reader_view",
Context.MODE_PRIVATE
)
val fontSizeKeyValue = prefs.getInt(fontSizeKey, 3)
@ -81,9 +81,9 @@ class ReaderViewRobot {
val prefs = InstrumentationRegistry.getInstrumentation()
.targetContext.getSharedPreferences(
"mozac_feature_reader_view",
Context.MODE_PRIVATE
)
"mozac_feature_reader_view",
Context.MODE_PRIVATE
)
assertEquals(expectedColorScheme, prefs.getString(colorSchemeKey, ""))
}

@ -94,7 +94,8 @@ private fun assertRecentlyClosedTabsMenuView() {
)
)
.check(
matches(withEffectiveVisibility(Visibility.VISIBLE)))
matches(withEffectiveVisibility(Visibility.VISIBLE))
)
}
private fun assertEmptyRecentlyClosedTabsList() =
@ -105,7 +106,8 @@ private fun assertEmptyRecentlyClosedTabsList() =
)
)
.check(
matches(withText("No recently closed tabs here")))
matches(withText("No recently closed tabs here"))
)
private fun assertPageUrl(expectedUrl: Uri) = onView(
allOf(
@ -116,7 +118,8 @@ private fun assertPageUrl(expectedUrl: Uri) = onView(
)
)
.check(
matches(withText(Matchers.containsString(expectedUrl.toString()))))
matches(withText(Matchers.containsString(expectedUrl.toString())))
)
private fun recentlyClosedTabsPageTitle() = onView(
allOf(
@ -128,9 +131,11 @@ private fun recentlyClosedTabsPageTitle() = onView(
private fun assertRecentlyClosedTabsPageTitle(title: String) {
recentlyClosedTabsPageTitle()
.check(
matches(withEffectiveVisibility(Visibility.VISIBLE)))
matches(withEffectiveVisibility(Visibility.VISIBLE))
)
.check(
matches(withText(title)))
matches(withText(title))
)
}
private fun recentlyClosedTabsThreeDotButton() =
@ -138,45 +143,50 @@ private fun recentlyClosedTabsThreeDotButton() =
allOf(
withId(R.id.overflow_menu),
withEffectiveVisibility(
Visibility.VISIBLE
Visibility.VISIBLE
)
)
)
)
private fun assertRecentlyClosedTabsMenuCopy() =
onView(withText("Copy"))
.check(
matches(
withEffectiveVisibility(Visibility.VISIBLE)))
withEffectiveVisibility(Visibility.VISIBLE)
)
)
private fun assertRecentlyClosedTabsMenuShare() =
onView(withText("Share"))
.check(
matches(
withEffectiveVisibility(Visibility.VISIBLE)))
withEffectiveVisibility(Visibility.VISIBLE)
)
)
private fun assertRecentlyClosedTabsOverlayNewTab() =
onView(withText("Open in new tab"))
.check(
matches(
withEffectiveVisibility(Visibility.VISIBLE))
)
withEffectiveVisibility(Visibility.VISIBLE)
)
)
private fun assertRecentlyClosedTabsMenuPrivateTab() =
onView(withText("Open in private tab"))
.check(
matches(
withEffectiveVisibility(Visibility.VISIBLE)
)
)
)
private fun assertRecentlyClosedTabsMenuDelete() =
onView(withText("Delete"))
.check(
matches(
withEffectiveVisibility(Visibility.VISIBLE)
)
)
)
)
private fun recentlyClosedTabsCopyButton() = onView(withText("Copy"))
@ -185,26 +195,31 @@ private fun copySnackBarText() = onView(withId(R.id.snackbar_text))
private fun assertCopySnackBarText() = copySnackBarText()
.check(
matches
(withText("URL copied")))
(withText("URL copied"))
)
private fun recentlyClosedTabsShareButton() = onView(withText("Share"))
private fun assertRecentlyClosedShareOverlay() =
onView(withId(R.id.shareWrapper))
.check(
matches(ViewMatchers.isDisplayed()))
matches(ViewMatchers.isDisplayed())
)
private fun assetRecentlyClosedShareTitle(title: String) =
onView(withId(R.id.share_tab_title))
.check(
matches(ViewMatchers.isDisplayed()))
matches(ViewMatchers.isDisplayed())
)
.check(
matches(withText(title)))
matches(withText(title))
)
private fun assertRecentlyClosedShareFavicon() =
onView(withId(R.id.share_tab_favicon))
.check(
matches(ViewMatchers.isDisplayed()))
matches(ViewMatchers.isDisplayed())
)
private fun assertRecentlyClosedShareUrl(expectedUrl: Uri) =
onView(
@ -214,7 +229,8 @@ private fun assertRecentlyClosedShareUrl(expectedUrl: Uri) =
)
)
.check(
matches(withText(Matchers.containsString(expectedUrl.toString()))))
matches(withText(Matchers.containsString(expectedUrl.toString())))
)
private fun recentlyClosedTabsNewTabButton() = onView(withText("Open in new tab"))

@ -73,8 +73,10 @@ class SearchRobot {
selectDefaultSearchEngine(searchEngineName)
fun clickSearchEngineShortcutButton() {
val searchEnginesShortcutButton = mDevice.findObject(UiSelector()
.resourceId("$packageName:id/search_engines_shortcut_button"))
val searchEnginesShortcutButton = mDevice.findObject(
UiSelector()
.resourceId("$packageName:id/search_engines_shortcut_button")
)
searchEnginesShortcutButton.waitForExists(waitingTime)
searchEnginesShortcutButton.click()
}
@ -270,7 +272,8 @@ private fun assertKeyboardVisibility(isExpectedToBeVisible: Boolean) = {
mDevice.waitNotNull(
Until.findObject(
By.text("Search Engine")
), waitingTime
),
waitingTime
)
assertEquals(
isExpectedToBeVisible,

@ -111,7 +111,7 @@ class SettingsRobot {
}
fun openAboutFirefoxPreview(interact: SettingsSubMenuAboutRobot.() -> Unit):
SettingsSubMenuAboutRobot.Transition {
SettingsSubMenuAboutRobot.Transition {
assertAboutFirefoxPreview().click()
@ -120,7 +120,7 @@ class SettingsRobot {
}
fun openSearchSubMenu(interact: SettingsSubMenuSearchRobot.() -> Unit):
SettingsSubMenuSearchRobot.Transition {
SettingsSubMenuSearchRobot.Transition {
fun searchEngineButton() = onView(withText("Search"))
searchEngineButton().click()
@ -401,7 +401,7 @@ private fun assertNotificationsButton() {
private fun assertDataCollectionButton() {
scrollToElementByText("Data collection")
onView(withText("Data collection"))
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
}
private fun openLinksInAppsButton() = onView(withText("Open links in apps"))

@ -117,8 +117,8 @@ private fun assertCurrentTimestamp() {
// Currently UI tests run against debug builds, which display a hard-coded string 'debug build'
// instead of the date. See https://github.com/mozilla-mobile/fenix/pull/10812#issuecomment-633746833
.check(matches(withText(containsString("debug build"))))
// This assertion should be valid for non-debug build types.
// .check(BuildDateAssertion.isDisplayedDateAccurate())
// This assertion should be valid for non-debug build types.
// .check(BuildDateAssertion.isDisplayedDateAccurate())
}
private fun assertWhatIsNewInFirefoxPreview() {

@ -59,8 +59,11 @@ private fun goBackButton() =
onView(withContentDescription("Navigate up"))
private fun assertNavigationToolBarHeader() = onView(
allOf(withParent(withId(R.id.navigationToolbar)),
withText(R.string.preferences_data_collection)))
allOf(
withParent(withId(R.id.navigationToolbar)),
withText(R.string.preferences_data_collection)
)
)
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
private fun assertDataCollectionOptions() {

@ -62,18 +62,27 @@ class SettingsSubMenuDeleteBrowsingDataOnQuitRobot {
private fun goBackButton() = onView(withContentDescription("Navigate up"))
private fun assertNavigationToolBarHeader() = onView(allOf(withId(R.id.navigationToolbar),
withChild(withText(R.string.preferences_delete_browsing_data_on_quit))))
private fun assertNavigationToolBarHeader() = onView(
allOf(
withId(R.id.navigationToolbar),
withChild(withText(R.string.preferences_delete_browsing_data_on_quit))
)
)
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
private fun deleteBrowsingOnQuitButton() = onView(allOf(withParentIndex(0),
withChild(withText(R.string.preferences_delete_browsing_data_on_quit))))
private fun deleteBrowsingOnQuitButton() = onView(
allOf(
withParentIndex(0),
withChild(withText(R.string.preferences_delete_browsing_data_on_quit))
)
)
private fun assertDeleteBrowsingOnQuitButton() = deleteBrowsingOnQuitButton()
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
private fun assertDeleteBrowsingOnQuitButtonSummary() = onView(
withText(R.string.preference_summary_delete_browsing_data_on_quit_2))
withText(R.string.preference_summary_delete_browsing_data_on_quit_2)
)
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
private fun assertDeleteBrowsingOnQuitButtonSwitchDefault() = onView(withResourceName("switch_widget"))

@ -86,8 +86,12 @@ private fun goBackButton() =
onView(allOf(withContentDescription("Navigate up")))
private fun assertNavigationToolBarHeader() {
onView(allOf(withId(R.id.navigationToolbar),
withChild(withText(R.string.preferences_delete_browsing_data))))
onView(
allOf(
withId(R.id.navigationToolbar),
withChild(withText(R.string.preferences_delete_browsing_data))
)
)
.check((matches(withEffectiveVisibility(Visibility.VISIBLE))))
}

@ -111,8 +111,12 @@ class SettingsSubMenuEnhancedTrackingProtectionRobot {
}
private fun assertNavigationToolBarHeader() {
onView(allOf(withParent(withId(org.mozilla.fenix.R.id.navigationToolbar)),
withText("Enhanced Tracking Protection")))
onView(
allOf(
withParent(withId(org.mozilla.fenix.R.id.navigationToolbar)),
withText("Enhanced Tracking Protection")
)
)
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
}
@ -122,21 +126,32 @@ private fun assertEnhancedTrackingProtectionHeader() {
}
private fun assertEnhancedTrackingProtectionHeaderDescription() {
onView(allOf(withParent(withParentIndex(0)),
withText("Keep your data to yourself. $appName protects you from many of the most common trackers that follow what you do online.")))
onView(
allOf(
withParent(withParentIndex(0)),
withText("Keep your data to yourself. $appName protects you from many of the most common trackers that follow what you do online.")
)
)
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
}
private fun assertLearnMoreText() {
onView(allOf(withParent(withParentIndex(0)),
withText("Learn more")))
onView(
allOf(
withParent(withParentIndex(0)),
withText("Learn more")
)
)
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
}
private fun assertEnhancedTrackingProtectionTextWithSwitchWidget() {
onView(allOf(
onView(
allOf(
withParentIndex(1),
withChild(withText("Enhanced Tracking Protection"))))
withChild(withText("Enhanced Tracking Protection"))
)
)
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
}
@ -195,7 +210,8 @@ private fun assertTrackingProtectionSwitchEnabled() {
}
private fun assertRadioButtonDefaults() {
onView(withText("Strict")
onView(
withText("Strict")
).assertIsChecked(false)
onView(
@ -205,7 +221,8 @@ private fun assertRadioButtonDefaults() {
)
).assertIsChecked(true)
onView(withText("Custom")
onView(
withText("Custom")
).assertIsChecked(false)
}

@ -18,10 +18,10 @@ import org.hamcrest.CoreMatchers
class SettingsSubMenuLoginsAndPasswordOptionsToSaveRobot {
fun verifySaveLoginsOptionsView() {
onView(ViewMatchers.withText("Ask to save"))
.check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
.check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
onView(ViewMatchers.withText("Never save"))
.check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
.check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
}
class Transition {
@ -35,4 +35,4 @@ class SettingsSubMenuLoginsAndPasswordOptionsToSaveRobot {
}
private fun goBackButton() =
onView(CoreMatchers.allOf(ViewMatchers.withContentDescription("Navigate up")))
onView(CoreMatchers.allOf(ViewMatchers.withContentDescription("Navigate up")))

@ -92,10 +92,10 @@ fun settingsSubMenuLoginsAndPassword(interact: SettingsSubMenuLoginsAndPasswordR
}
private fun goBackButton() =
onView(CoreMatchers.allOf(ViewMatchers.withContentDescription("Navigate up")))
onView(CoreMatchers.allOf(ViewMatchers.withContentDescription("Navigate up")))
private fun assertDefaultView() = onView(ViewMatchers.withText("Sync logins across devices"))
.check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
.check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
private fun assertDefaultValueAutofillLogins() = onView(ViewMatchers.withText("Autofill"))
.check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
@ -104,4 +104,4 @@ private fun assertDefaultValueExceptions() = onView(ViewMatchers.withText("Excep
.check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
private fun assertDefaultValueSyncLogins() = onView(ViewMatchers.withText("Sign in to Sync"))
.check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
.check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))

@ -46,13 +46,13 @@ class SettingsTurnOnSyncRobot {
}
private fun goBackButton() =
Espresso.onView(CoreMatchers.allOf(ViewMatchers.withContentDescription("Navigate up")))
Espresso.onView(CoreMatchers.allOf(ViewMatchers.withContentDescription("Navigate up")))
private fun assertUseEmailField() = Espresso.onView(ViewMatchers.withText("Use email instead"))
.check(ViewAssertions.matches(ViewMatchers.withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
.check(ViewAssertions.matches(ViewMatchers.withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
private fun assertReadyToScan() = Espresso.onView(ViewMatchers.withText("Ready to scan"))
.check(ViewAssertions.matches(ViewMatchers.withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
.check(ViewAssertions.matches(ViewMatchers.withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
private fun useEmailButton() = Espresso.onView(ViewMatchers.withText("Use email instead"))

@ -39,7 +39,8 @@ fun systemSettings(interact: SystemSettingsRobot.() -> Unit): SystemSettingsRobo
private fun assertSystemNotificationsView() {
mDevice.findObject(UiSelector().resourceId("com.android.settings:id/list"))
.waitForExists(waitingTime)
assertTrue(mDevice.findObject(UiSelector().textContains("Show notifications"))
.waitForExists(waitingTime)
assertTrue(
mDevice.findObject(UiSelector().textContains("Show notifications"))
.waitForExists(waitingTime)
)
}

@ -230,8 +230,10 @@ class TabDrawerRobot {
fun openTabDrawer(interact: TabDrawerRobot.() -> Unit): TabDrawerRobot.Transition {
mDevice.waitForIdle(waitingTime)
tabsCounter().click()
mDevice.waitNotNull(Until.findObject(By.res("$packageName:id/tab_layout")),
waitingTime)
mDevice.waitNotNull(
Until.findObject(By.res("$packageName:id/tab_layout")),
waitingTime
)
TabDrawerRobot().interact()
return TabDrawerRobot.Transition()
@ -338,7 +340,7 @@ class TabDrawerRobot {
}
fun openRecentlyClosedTabs(interact: RecentlyClosedTabsRobot.() -> Unit):
RecentlyClosedTabsRobot.Transition {
RecentlyClosedTabsRobot.Transition {
threeDotMenu().click()
@ -356,7 +358,7 @@ class TabDrawerRobot {
}
fun clickSaveCollection(interact: CollectionRobot.() -> Unit):
CollectionRobot.Transition {
CollectionRobot.Transition {
saveTabsToCollectionButton().click()
CollectionRobot().interact()
@ -395,9 +397,11 @@ private fun threeDotMenu() = onView(withId(R.id.tab_tray_overflow))
private fun assertExistingOpenTabs(title: String) {
try {
mDevice.findObject(UiSelector()
.resourceId("$packageName:id/mozac_browser_tabstray_title")
.textContains(title))
mDevice.findObject(
UiSelector()
.resourceId("$packageName:id/mozac_browser_tabstray_title")
.textContains(title)
)
.waitForExists(waitingTime)
tab(title).check(matches(isDisplayed()))

@ -34,7 +34,8 @@ class ThreeDotMenuHistoryItemRobot {
mDevice.waitNotNull(
Until.findObject(
By.text("ALL ACTIONS")
), TestAssetHelper.waitingTime
),
TestAssetHelper.waitingTime
)
LibrarySubMenusMultipleSelectionToolbarRobot().interact()

@ -512,7 +512,8 @@ private fun tabSettingsButton() =
private fun assertTabSettingsButton() {
tabSettingsButton()
.check(
matches(isDisplayed()))
matches(isDisplayed())
)
}
private fun recentlyClosedTabsButton() =
@ -521,7 +522,8 @@ private fun recentlyClosedTabsButton() =
private fun assertRecentlyClosedTabsButton() {
recentlyClosedTabsButton()
.check(
matches(isDisplayed()))
matches(isDisplayed())
)
}
private fun shareAllTabsButton() =
@ -530,7 +532,8 @@ private fun shareAllTabsButton() =
private fun assertShareAllTabsButton() {
shareAllTabsButton()
.check(
matches(isDisplayed()))
matches(isDisplayed())
)
}
private fun assertNewTabButton() = onView(withText("New tab")).check(matches(isDisplayed()))

@ -140,7 +140,8 @@ open class FenixApplication : LocaleAwareApplication(), Provider {
channel = BuildConfig.BUILD_TYPE,
httpClient = ConceptFetchHttpUploader(
lazy(LazyThreadSafetyMode.NONE) { components.core.client }
)),
)
),
uploadEnabled = telemetryEnabled,
buildInfo = GleanBuildInfo.buildInfo
)
@ -392,15 +393,17 @@ open class FenixApplication : LocaleAwareApplication(), Provider {
logger.info("onTrimMemory(), level=$level, main=${isMainProcess()}")
components.analytics.crashReporter.recordCrashBreadcrumb(Breadcrumb(
category = "Memory",
message = "onTrimMemory()",
data = mapOf(
"level" to level.toString(),
"main" to isMainProcess().toString()
),
level = Breadcrumb.Level.INFO
))
components.analytics.crashReporter.recordCrashBreadcrumb(
Breadcrumb(
category = "Memory",
message = "onTrimMemory()",
data = mapOf(
"level" to level.toString(),
"main" to isMainProcess().toString()
),
level = Breadcrumb.Level.INFO
)
)
runOnlyInMainProcess {
components.core.icons.onTrimMemory(level)
@ -473,22 +476,24 @@ open class FenixApplication : LocaleAwareApplication(), Provider {
components.core.store,
onNewTabOverride = {
_, engineSession, url ->
val shouldCreatePrivateSession =
components.core.store.state.selectedTab?.content?.private
?: components.settings.openLinksInAPrivateTab
components.useCases.tabsUseCases.addTab(
url = url,
selectTab = true,
engineSession = engineSession,
private = shouldCreatePrivateSession
)
val shouldCreatePrivateSession =
components.core.store.state.selectedTab?.content?.private
?: components.settings.openLinksInAPrivateTab
components.useCases.tabsUseCases.addTab(
url = url,
selectTab = true,
engineSession = engineSession,
private = shouldCreatePrivateSession
)
},
onCloseTabOverride = {
_, sessionId -> components.useCases.tabsUseCases.removeTab(sessionId)
_, sessionId ->
components.useCases.tabsUseCases.removeTab(sessionId)
},
onSelectTabOverride = {
_, sessionId -> components.useCases.tabsUseCases.selectTab(sessionId)
_, sessionId ->
components.useCases.tabsUseCases.selectTab(sessionId)
},
onExtensionsLoaded = { extensions ->
components.addonUpdater.registerForFutureUpdates(extensions)

@ -964,9 +964,9 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity {
// First time opening this activity in the task.
// Cold start / start from Recents after back press.
return activityIcicle == null &&
// Activity was restarted from Recents after it was destroyed by Android while in background
// in cases of memory pressure / "Don't keep activities".
startingIntent.flags and Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY == 0
// Activity was restarted from Recents after it was destroyed by Android while in background
// in cases of memory pressure / "Don't keep activities".
startingIntent.flags and Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY == 0
}
/**

@ -18,7 +18,8 @@ import org.mozilla.fenix.ext.showToolbar
/**
* A fragment to show the permissions of an add-on.
*/
class AddonPermissionsDetailsFragment : Fragment(R.layout.fragment_add_on_permissions),
class AddonPermissionsDetailsFragment :
Fragment(R.layout.fragment_add_on_permissions),
AddonPermissionsDetailsInteractor {
private val args by navArgs<AddonPermissionsDetailsFragmentArgs>()

@ -45,7 +45,8 @@ abstract class AddonPopupBaseFragment : Fragment(), EngineSession.Observer, User
fragmentManager = parentFragmentManager,
onNeedToRequestPermissions = { permissions ->
requestPermissions(permissions, REQUEST_CODE_PROMPT_PERMISSIONS)
}),
}
),
owner = this,
view = view
)

@ -108,8 +108,9 @@ class AddonsManagementFragment : Fragment(R.layout.fragment_add_ons_management)
val addons = requireContext().components.addonManager.getAddons(allowCache = allowCache)
// Add-ons that should be excluded in Mozilla Online builds
val excludedAddonIDs = if (Config.channel.isMozillaOnline &&
!BuildConfig.MOZILLA_ONLINE_ADDON_EXCLUSIONS.isNullOrEmpty()) {
BuildConfig.MOZILLA_ONLINE_ADDON_EXCLUSIONS.toList()
!BuildConfig.MOZILLA_ONLINE_ADDON_EXCLUSIONS.isNullOrEmpty()
) {
BuildConfig.MOZILLA_ONLINE_ADDON_EXCLUSIONS.toList()
} else {
emptyList<String>()
}
@ -200,7 +201,7 @@ class AddonsManagementFragment : Fragment(R.layout.fragment_add_ons_management)
private fun hasExistingAddonInstallationDialogFragment(): Boolean {
return parentFragmentManager.findFragmentByTag(INSTALLATION_DIALOG_FRAGMENT_TAG)
as? AddonInstallationDialogFragment != null
as? AddonInstallationDialogFragment != null
}
@VisibleForTesting

@ -148,8 +148,12 @@ import mozilla.components.feature.session.behavior.ToolbarPosition as MozacToolb
*/
@ExperimentalCoroutinesApi
@Suppress("TooManyFunctions", "LargeClass")
abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, ActivityResultHandler,
OnBackLongPressedListener, AccessibilityManager.AccessibilityStateChangeListener {
abstract class BaseBrowserFragment :
Fragment(),
UserInteractionHandler,
ActivityResultHandler,
OnBackLongPressedListener,
AccessibilityManager.AccessibilityStateChangeListener {
private lateinit var browserFragmentStore: BrowserFragmentStore
private lateinit var browserAnimator: BrowserAnimator
@ -235,25 +239,25 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Activit
}
final override fun onViewCreated(view: View, savedInstanceState: Bundle?) =
PerfStartup.baseBfragmentOnViewCreated.measureNoInline { // weird indentation to avoid breaking blame.
initializeUI(view)
if (customTabSessionId == null) {
// We currently only need this observer to navigate to home
// in case all tabs have been removed on startup. No need to
// this if we have a known session to display.
observeRestoreComplete(requireComponents.core.store, findNavController())
}
PerfStartup.baseBfragmentOnViewCreated.measureNoInline { // weird indentation to avoid breaking blame.
initializeUI(view)
if (customTabSessionId == null) {
// We currently only need this observer to navigate to home
// in case all tabs have been removed on startup. No need to
// this if we have a known session to display.
observeRestoreComplete(requireComponents.core.store, findNavController())
}
observeTabSelection(requireComponents.core.store)
observeTabSelection(requireComponents.core.store)
if (!onboarding.userHasBeenOnboarded()) {
observeTabSource(requireComponents.core.store)
}
if (!onboarding.userHasBeenOnboarded()) {
observeTabSource(requireComponents.core.store)
}
requireContext().accessibilityManager.addAccessibilityStateChangeListener(this)
Unit
}
requireContext().accessibilityManager.addAccessibilityStateChangeListener(this)
Unit
}
private fun initializeUI(view: View) {
val tab = getCurrentTab()
@ -823,15 +827,17 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Activit
internal fun expandToolbarOnNavigation(store: BrowserStore) {
consumeFlow(store) { flow ->
flow.mapNotNull {
state -> state.findCustomTabOrSelectedTab(customTabSessionId)
}
.ifAnyChanged {
tab -> arrayOf(tab.content.url, tab.content.loadRequest)
}
.collect {
findInPageIntegration.onBackPressed()
browserToolbarView.expand()
state ->
state.findCustomTabOrSelectedTab(customTabSessionId)
}
.ifAnyChanged {
tab ->
arrayOf(tab.content.url, tab.content.loadRequest)
}
.collect {
findInPageIntegration.onBackPressed()
browserToolbarView.expand()
}
}
}
@ -907,8 +913,8 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Activit
@VisibleForTesting
internal fun shouldPullToRefreshBeEnabled(inFullScreen: Boolean): Boolean {
return FeatureFlags.pullToRefreshEnabled &&
requireContext().settings().isPullToRefreshEnabledInBrowser &&
!inFullScreen
requireContext().settings().isPullToRefreshEnabledInBrowser &&
!inFullScreen
}
@VisibleForTesting
@ -981,12 +987,12 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Activit
flow.ifChanged {
it.selectedTabId
}
.mapNotNull {
it.selectedTab
}
.collect {
handleTabSelected(it)
}
.mapNotNull {
it.selectedTab
}
.collect {
handleTabSelected(it)
}
}
}
@ -998,14 +1004,14 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Activit
state.selectedTab
}
.collect {
if (!onboarding.userHasBeenOnboarded() &&
it.content.loadRequest?.triggeredByRedirect != true &&
it.source !in intentSourcesList &&
it.content.url !in onboardingLinksList
) {
onboarding.finish()
if (!onboarding.userHasBeenOnboarded() &&
it.content.loadRequest?.triggeredByRedirect != true &&
it.source !in intentSourcesList &&
it.content.url !in onboardingLinksList
) {
onboarding.finish()
}
}
}
}
}
@ -1070,10 +1076,10 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Activit
@CallSuper
override fun onBackPressed(): Boolean {
return findInPageIntegration.onBackPressed() ||
fullScreenFeature.onBackPressed() ||
promptsFeature.onBackPressed() ||
sessionFeature.onBackPressed() ||
removeSessionIfNeeded()
fullScreenFeature.onBackPressed() ||
promptsFeature.onBackPressed() ||
sessionFeature.onBackPressed() ||
removeSessionIfNeeded()
}
override fun onBackLongPressed(): Boolean {

@ -28,7 +28,8 @@ class FenixSnackbarDelegate(private val view: View) : ContextMenuCandidate.Snack
.setAction(view.context.getString(action)) { listener.invoke(view) }
.show()
} else {
FenixSnackbar.make(view,
FenixSnackbar.make(
view,
duration = FenixSnackbar.LENGTH_SHORT,
isDisplayedWithBrowserToolbar = true
)

@ -58,22 +58,23 @@ class OpenInAppOnboardingObserver(
flow.mapNotNull { state ->
state.selectedTab
}
.ifAnyChanged {
tab -> arrayOf(tab.content.url, tab.content.loading)
}
.collect { tab ->
if (tab.content.url != currentUrl) {
sessionDomainForDisplayedBanner?.let {
if (tab.content.url.tryGetHostFromUrl() != it) {
infoBanner?.dismiss()
.ifAnyChanged {
tab ->
arrayOf(tab.content.url, tab.content.loading)
}
.collect { tab ->
if (tab.content.url != currentUrl) {
sessionDomainForDisplayedBanner?.let {
if (tab.content.url.tryGetHostFromUrl() != it) {
infoBanner?.dismiss()
}
}
currentUrl = tab.content.url
} else {
// Loading state has changed
maybeShowOpenInAppBanner(tab.content.url, tab.content.loading)
}
currentUrl = tab.content.url
} else {
// Loading state has changed
maybeShowOpenInAppBanner(tab.content.url, tab.content.loading)
}
}
}
}

@ -214,8 +214,10 @@ class ToolbarGestureHandler(
val reverseFling =
abs(velocityX) >= minimumFlingVelocity && !velocityMatchesDirection
return !reverseFling && (previewWidth / windowWidth >= GESTURE_FINISH_PERCENT ||
abs(velocityX) >= minimumFlingVelocity)
return !reverseFling && (
previewWidth / windowWidth >= GESTURE_FINISH_PERCENT ||
abs(velocityX) >= minimumFlingVelocity
)
}
private fun getAnimator(finalContextX: Float, duration: Long): ValueAnimator {

@ -170,9 +170,12 @@ class CollectionCreationView(
setOnClickListener {
name_collection_edittext.hideKeyboard()
val handler = Handler(Looper.getMainLooper())
handler.postDelayed({
interactor.onBackPressed(SaveCollectionStep.NameCollection)
}, TRANSITION_DURATION)
handler.postDelayed(
{
interactor.onBackPressed(SaveCollectionStep.NameCollection)
},
TRANSITION_DURATION
)
}
}
@ -216,9 +219,12 @@ class CollectionCreationView(
setOnClickListener {
name_collection_edittext.hideKeyboard()
val handler = Handler(Looper.getMainLooper())
handler.postDelayed({
interactor.onBackPressed(SaveCollectionStep.RenameCollection)
}, TRANSITION_DURATION)
handler.postDelayed(
{
interactor.onBackPressed(SaveCollectionStep.RenameCollection)
},
TRANSITION_DURATION
)
}
}
transition.addListener(object : Transition.TransitionListener {

@ -129,7 +129,8 @@ class Components(private val context: Context) {
@Suppress("MagicNumber")
val supportedAddonsChecker by lazyMonitored {
DefaultSupportedAddonsChecker(context, SupportedAddonsChecker.Frequency(12, TimeUnit.HOURS),
DefaultSupportedAddonsChecker(
context, SupportedAddonsChecker.Frequency(12, TimeUnit.HOURS),
onNotificationClickIntent = Intent(context, HomeActivity::class.java).apply {
action = Intent.ACTION_VIEW
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK

@ -105,7 +105,7 @@ class Core(
val defaultSettings = DefaultSettings(
requestInterceptor = requestInterceptor,
remoteDebuggingEnabled = context.settings().isRemoteDebuggingEnabled &&
Build.VERSION.SDK_INT >= Build.VERSION_CODES.M,
Build.VERSION.SDK_INT >= Build.VERSION_CODES.M,
testingModeEnabled = false,
trackingProtectionPolicy = trackingProtectionPolicyFactory.createTrackingProtectionPolicy(),
historyTrackingDelegate = HistoryDelegate(lazyHistoryStorage),
@ -432,7 +432,7 @@ class Core(
fun getPreferredColorScheme(): PreferredColorScheme {
val inDark =
(context.resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK) ==
Configuration.UI_MODE_NIGHT_YES
Configuration.UI_MODE_NIGHT_YES
return when {
context.settings().shouldUseDarkTheme -> PreferredColorScheme.Dark
context.settings().shouldUseLightTheme -> PreferredColorScheme.Light

@ -39,10 +39,10 @@ enum class IntentProcessorType {
fun IntentProcessors.getType(processor: IntentProcessor?) = when {
migrationIntentProcessor == processor -> IntentProcessorType.MIGRATION
externalAppIntentProcessors.contains(processor) ||
customTabIntentProcessor == processor ||
privateCustomTabIntentProcessor == processor -> IntentProcessorType.EXTERNAL_APP
customTabIntentProcessor == processor ||
privateCustomTabIntentProcessor == processor -> IntentProcessorType.EXTERNAL_APP
intentProcessor == processor ||
privateIntentProcessor == processor ||
fennecPageShortcutIntentProcessor == processor -> IntentProcessorType.NEW_TAB
privateIntentProcessor == processor ||
fennecPageShortcutIntentProcessor == processor -> IntentProcessorType.NEW_TAB
else -> IntentProcessorType.OTHER
}

@ -38,15 +38,17 @@ object PrivateShortcutCreateManager {
)
)
.setIcon(icon)
.setIntent(Intent(context, HomeActivity::class.java).apply {
action = Intent.ACTION_VIEW
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
putExtra(HomeActivity.PRIVATE_BROWSING_MODE, true)
putExtra(
HomeActivity.OPEN_TO_SEARCH,
StartSearchIntentProcessor.PRIVATE_BROWSING_PINNED_SHORTCUT
)
})
.setIntent(
Intent(context, HomeActivity::class.java).apply {
action = Intent.ACTION_VIEW
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
putExtra(HomeActivity.PRIVATE_BROWSING_MODE, true)
putExtra(
HomeActivity.OPEN_TO_SEARCH,
StartSearchIntentProcessor.PRIVATE_BROWSING_PINNED_SHORTCUT
)
}
)
.build()
val homeScreenIntent = Intent(Intent.ACTION_MAIN)
.addCategory(Intent.CATEGORY_HOME)

@ -41,7 +41,8 @@ class Services(
interceptLinkClicks = true,
launchInApp = {
PreferenceManager.getDefaultSharedPreferences(context).getBoolean(
context.getPreferenceKey(R.string.pref_key_open_links_in_external_app), false)
context.getPreferenceKey(R.string.pref_key_open_links_in_external_app), false
)
}
)
}

@ -25,7 +25,8 @@ class ActivationPing(private val context: Context) {
private val prefs: SharedPreferences by lazy {
context.getSharedPreferences(
"${this.javaClass.canonicalName}.prefs", Context.MODE_PRIVATE)
"${this.javaClass.canonicalName}.prefs", Context.MODE_PRIVATE
)
}
/**

@ -27,7 +27,7 @@ class SecurePrefsTelemetry(
experiments.withExperiment(FeatureId.ANDROID_KEYSTORE) { experimentBranch ->
// .. and this device is not in the control group.
if (experimentBranch == ExperimentBranch.TREATMENT) {
SecurePrefsReliabilityExperiment(appContext)()
SecurePrefsReliabilityExperiment(appContext)()
}
}
}

@ -59,7 +59,7 @@ class MasterPasswordTipProvider(
override val shouldDisplay: Boolean by lazy {
context.settings().shouldDisplayMasterPasswordMigrationTip &&
fennecLoginsMPImporter?.hasMasterPassword() == true
fennecLoginsMPImporter?.hasMasterPassword() == true
}
private fun masterPasswordMigrationTip(): Tip =

@ -92,9 +92,11 @@ class MigrationTipProvider(private val context: Context) : TipProvider {
return if (MozillaProductDetector.packageIsInstalled(context, FENIX.productName)) {
context.startActivity(context.packageManager.getLaunchIntentForPackage(FENIX.productName))
} else {
context.startActivity(Intent(
Intent.ACTION_VIEW, Uri.parse(SupportUtils.FIREFOX_NIGHTLY_PLAY_STORE_URL)
))
context.startActivity(
Intent(
Intent.ACTION_VIEW, Uri.parse(SupportUtils.FIREFOX_NIGHTLY_PLAY_STORE_URL)
)
)
}
}

@ -180,8 +180,10 @@ private fun BrowserStore.updateSearchTermsOfSelectedSession(
) {
val selectedTabId = state.selectedTabId ?: return
dispatch(ContentAction.UpdateSearchTermsAction(
selectedTabId,
searchTerms
))
dispatch(
ContentAction.UpdateSearchTermsAction(
selectedTabId,
searchTerms
)
)
}

@ -118,13 +118,15 @@ class DefaultBrowserToolbarMenuController(
customTabUseCases.migrate(customTabSessionId, select = true)
// Switch to the actual browser which should now display our new selected session
activity.startActivity(openInFenixIntent.apply {
// We never want to launch the browser in the same task as the external app
// activity. So we force a new task here. IntentReceiverActivity will do the
// right thing and take care of routing to an already existing browser and avoid
// cloning a new one.
flags = flags or Intent.FLAG_ACTIVITY_NEW_TASK
})
activity.startActivity(
openInFenixIntent.apply {
// We never want to launch the browser in the same task as the external app
// activity. So we force a new task here. IntentReceiverActivity will do the
// right thing and take care of routing to an already existing browser and avoid
// cloning a new one.
flags = flags or Intent.FLAG_ACTIVITY_NEW_TASK
}
)
// Close this activity (and the task) since it is no longer displaying any session
activity.finishAndRemoveTask()

@ -68,7 +68,7 @@ class BrowserToolbarView(
@VisibleForTesting
internal val isPwaTabOrTwaTab: Boolean
get() = customTabSession?.config?.externalAppType == ExternalAppType.PROGRESSIVE_WEB_APP ||
customTabSession?.config?.externalAppType == ExternalAppType.TRUSTED_WEB_ACTIVITY
customTabSession?.config?.externalAppType == ExternalAppType.TRUSTED_WEB_ACTIVITY
init {
val isCustomTabSession = customTabSession != null

@ -158,12 +158,12 @@ open class DefaultToolbarMenu(
@VisibleForTesting(otherwise = PRIVATE)
fun canAddToHomescreen(): Boolean =
selectedSession != null && isPinningSupported &&
!context.components.useCases.webAppUseCases.isInstallable()
!context.components.useCases.webAppUseCases.isInstallable()
@VisibleForTesting(otherwise = PRIVATE)
fun canInstall(): Boolean =
selectedSession != null && isPinningSupported &&
context.components.useCases.webAppUseCases.isInstallable()
context.components.useCases.webAppUseCases.isInstallable()
@VisibleForTesting(otherwise = PRIVATE)
fun shouldShowOpenInApp(): Boolean = selectedSession?.let { session ->

@ -134,7 +134,7 @@ class DefaultToolbarIntegration(
DisplayToolbar.Indicators.HIGHLIGHT
)
}
context.settings().shouldUseTrackingProtection
context.settings().shouldUseTrackingProtection
toolbar.display.icons = toolbar.display.icons.copy(
emptyIcon = null,
@ -155,11 +155,11 @@ class DefaultToolbarIntegration(
interactor.onTabCounterMenuItemTapped(it)
},
iconColor =
if (isPrivate) {
ContextCompat.getColor(context, R.color.primary_text_private_theme)
} else {
null
}
if (isPrivate) {
ContextCompat.getColor(context, R.color.primary_text_private_theme)
} else {
null
}
).also {
it.updateMenu(context.settings().toolbarPosition)
}

@ -37,11 +37,13 @@ fun Activity.enterToImmersiveMode() {
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
// This will be addressed on https://github.com/mozilla-mobile/fenix/issues/17804
@Suppress("DEPRECATION")
window.decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
window.decorView.systemUiVisibility = (
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
or View.SYSTEM_UI_FLAG_FULLSCREEN
or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY)
or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
)
}
fun Activity.breadcrumb(

@ -18,7 +18,7 @@ fun ConnectivityManager.isOnline(network: Network? = null): Boolean {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
getNetworkCapabilities(network ?: activeNetwork)?.let {
it.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) &&
it.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)
it.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)
} ?: false
} else {
// for devices below android M, there's no better way to get this.

@ -31,9 +31,15 @@ fun TabCollection.getIconColor(context: Context): Int {
* Then get the numbers from all these default names, compute the maximum number and add one.
*/
fun List<TabCollection>.getDefaultCollectionNumber(): Int {
return (this
.map { it.title }
.filter { it.matches(Regex("Collection\\s\\d+")) }
.map { Integer.valueOf(it.split(" ")[DefaultCollectionCreationController.DEFAULT_COLLECTION_NUMBER_POSITION]) }
.maxOrNull() ?: 0) + DefaultCollectionCreationController.DEFAULT_INCREMENT_VALUE
return (
this
.map { it.title }
.filter { it.matches(Regex("Collection\\s\\d+")) }
.map {
Integer.valueOf(
it.split(" ")[DefaultCollectionCreationController.DEFAULT_COLLECTION_NUMBER_POSITION]
)
}
.maxOrNull() ?: 0
) + DefaultCollectionCreationController.DEFAULT_INCREMENT_VALUE
}

@ -77,16 +77,19 @@ object GeckoProvider {
.getHashUrl(CN_GET_HASH_URL)
.build()
runtimeSettings.contentBlocking.setSafeBrowsingProviders(mozcn,
runtimeSettings.contentBlocking.setSafeBrowsingProviders(
mozcn,
// Keep the existing configuration
ContentBlocking.GOOGLE_SAFE_BROWSING_PROVIDER,
ContentBlocking.GOOGLE_LEGACY_SAFE_BROWSING_PROVIDER)
ContentBlocking.GOOGLE_LEGACY_SAFE_BROWSING_PROVIDER
)
runtimeSettings.contentBlocking.setSafeBrowsingPhishingTable(
"m6eb-phish-shavar",
"m6ib-phish-shavar",
// Existing configuration
"goog-phish-proto")
"goog-phish-proto"
)
}
val geckoRuntime = GeckoRuntime.create(context, runtimeSettings)

@ -92,7 +92,7 @@ class HistoryMetadataMiddleware(
// When history state is ready, we can record metadata for this page.
val knownHistoryMetadata = tab.historyMetadata
val metadataPresentForUrl = knownHistoryMetadata != null &&
knownHistoryMetadata.url == tab.content.url
knownHistoryMetadata.url == tab.content.url
// Record metadata for tab if there is no metadata present, or if url of the
// tab changes since we last recorded metadata.
if (!metadataPresentForUrl) {

@ -198,7 +198,8 @@ class HomeFragment : Fragment() {
if (!onboarding.userHasBeenOnboarded() &&
requireContext().settings().shouldShowPrivacyPopWindow &&
Config.channel.isMozillaOnline) {
Config.channel.isMozillaOnline
) {
showPrivacyPopWindow(requireContext(), requireActivity())
}
}
@ -665,22 +666,25 @@ class HomeFragment : Fragment() {
currentMode,
owner = this@HomeFragment.viewLifecycleOwner
)
requireComponents.backgroundServices.accountManager.register(object : AccountObserver {
override fun onAuthenticated(account: OAuthAccount, authType: AuthType) {
if (authType != AuthType.Existing) {
view?.let {
FenixSnackbar.make(
view = it,
duration = Snackbar.LENGTH_SHORT,
isDisplayedWithBrowserToolbar = false
)
.setText(it.context.getString(R.string.onboarding_firefox_account_sync_is_on))
.setAnchorView(toolbarLayout)
.show()
requireComponents.backgroundServices.accountManager.register(
object : AccountObserver {
override fun onAuthenticated(account: OAuthAccount, authType: AuthType) {
if (authType != AuthType.Existing) {
view?.let {
FenixSnackbar.make(
view = it,
duration = Snackbar.LENGTH_SHORT,
isDisplayedWithBrowserToolbar = false
)
.setText(it.context.getString(R.string.onboarding_firefox_account_sync_is_on))
.setAnchorView(toolbarLayout)
.show()
}
}
}
}
}, owner = this@HomeFragment.viewLifecycleOwner)
},
owner = this@HomeFragment.viewLifecycleOwner
)
}
if (browsingModeManager.mode.isPrivate &&
@ -701,7 +705,8 @@ class HomeFragment : Fragment() {
private fun navToSavedLogins() {
findNavController().navigate(
HomeFragmentDirections.actionGlobalSavedLoginsAuthFragment())
HomeFragmentDirections.actionGlobalSavedLoginsAuthFragment()
)
}
private fun dispatchModeChanges(mode: Mode) {

@ -181,7 +181,8 @@ class HomeMenu(
// We don't want to cause its initialization just for this check.
val accountAuthItem =
if (context.components.backgroundServices.accountManagerAvailableQueue.isReady() &&
context.components.backgroundServices.accountManager.accountNeedsReauth()) {
context.components.backgroundServices.accountManager.accountNeedsReauth()
) {
reconnectToSyncItem
} else {
null
@ -220,37 +221,40 @@ class HomeMenu(
if (lifecycleOwner.lifecycle.currentState == Lifecycle.State.DESTROYED) {
return@runIfReadyOrQueue
}
context.components.backgroundServices.accountManager.register(object : AccountObserver {
override fun onAuthenticationProblems() {
lifecycleOwner.lifecycleScope.launch(Dispatchers.Main) {
onMenuBuilderChanged(
BrowserMenuBuilder(
menuItems
context.components.backgroundServices.accountManager.register(
object : AccountObserver {
override fun onAuthenticationProblems() {
lifecycleOwner.lifecycleScope.launch(Dispatchers.Main) {
onMenuBuilderChanged(
BrowserMenuBuilder(
menuItems
)
)
)
}
}
}
override fun onAuthenticated(account: OAuthAccount, authType: AuthType) {
lifecycleOwner.lifecycleScope.launch(Dispatchers.Main) {
onMenuBuilderChanged(
BrowserMenuBuilder(
menuItems
override fun onAuthenticated(account: OAuthAccount, authType: AuthType) {
lifecycleOwner.lifecycleScope.launch(Dispatchers.Main) {
onMenuBuilderChanged(
BrowserMenuBuilder(
menuItems
)
)
)
}
}
}
override fun onLoggedOut() {
lifecycleOwner.lifecycleScope.launch(Dispatchers.Main) {
onMenuBuilderChanged(
BrowserMenuBuilder(
menuItems
override fun onLoggedOut() {
lifecycleOwner.lifecycleScope.launch(Dispatchers.Main) {
onMenuBuilderChanged(
BrowserMenuBuilder(
menuItems
)
)
)
}
}
}
}, lifecycleOwner)
},
lifecycleOwner
)
}
}
}

@ -29,21 +29,31 @@ fun showPrivacyPopWindow(context: Context, activity: Activity) {
val clickableSpan2 = PrivacyContentSpan(Position.POS2, context)
val clickableSpan3 = PrivacyContentSpan(Position.POS3, context)
messageSpannable.setSpan(clickableSpan1, content.indexOf(messageClickable1),
content.indexOf(messageClickable1) + messageClickable1.length, Spanned.SPAN_INCLUSIVE_INCLUSIVE)
messageSpannable.setSpan(clickableSpan2, content.indexOf(messageClickable2),
content.indexOf(messageClickable2) + messageClickable2.length, Spanned.SPAN_INCLUSIVE_INCLUSIVE)
messageSpannable.setSpan(clickableSpan3, content.indexOf(messageClickable3),
content.indexOf(messageClickable3) + messageClickable3.length, Spanned.SPAN_INCLUSIVE_INCLUSIVE)
messageSpannable.setSpan(
clickableSpan1, content.indexOf(messageClickable1),
content.indexOf(messageClickable1) + messageClickable1.length, Spanned.SPAN_INCLUSIVE_INCLUSIVE
)
messageSpannable.setSpan(
clickableSpan2, content.indexOf(messageClickable2),
content.indexOf(messageClickable2) + messageClickable2.length, Spanned.SPAN_INCLUSIVE_INCLUSIVE
)
messageSpannable.setSpan(
clickableSpan3, content.indexOf(messageClickable3),
content.indexOf(messageClickable3) + messageClickable3.length, Spanned.SPAN_INCLUSIVE_INCLUSIVE
)
// Users can only use fenix after they agree with the privacy notice
val builder = AlertDialog.Builder(activity)
.setPositiveButton(context.getString(R.string.privacy_notice_positive_button),
.setPositiveButton(
context.getString(R.string.privacy_notice_positive_button),
DialogInterface.OnClickListener { _, _ ->
context.settings().shouldShowPrivacyPopWindow = false
})
.setNeutralButton(context.getString(R.string.privacy_notice_neutral_button),
DialogInterface.OnClickListener { _, _ -> exitProcess(0) })
}
)
.setNeutralButton(
context.getString(R.string.privacy_notice_neutral_button),
DialogInterface.OnClickListener { _, _ -> exitProcess(0) }
)
.setTitle(context.getString(R.string.privacy_notice_title))
.setMessage(messageSpannable)
.setCancelable(false)

@ -197,28 +197,28 @@ sealed class AdapterItem(@LayoutRes val viewType: Int) {
data class RecentBookmarks(val recentBookmarks: List<BookmarkNode>) :
AdapterItem(RecentBookmarksViewHolder.LAYOUT_ID) {
override fun sameAs(other: AdapterItem): Boolean {
val newBookmarks = (other as? RecentBookmarks) ?: return false
if (newBookmarks.recentBookmarks.size != this.recentBookmarks.size) {
return false
}
override fun sameAs(other: AdapterItem): Boolean {
val newBookmarks = (other as? RecentBookmarks) ?: return false
if (newBookmarks.recentBookmarks.size != this.recentBookmarks.size) {
return false
}
return recentBookmarks.zip(newBookmarks.recentBookmarks).all { (new, old) ->
new.guid == old.guid
}
return recentBookmarks.zip(newBookmarks.recentBookmarks).all { (new, old) ->
new.guid == old.guid
}
}
override fun contentsSameAs(other: AdapterItem): Boolean {
val newBookmarks = (other as? RecentBookmarks) ?: return false
override fun contentsSameAs(other: AdapterItem): Boolean {
val newBookmarks = (other as? RecentBookmarks) ?: return false
val newBookmarksSequence = newBookmarks.recentBookmarks.asSequence()
val oldBookmarksList = this.recentBookmarks.asSequence()
val newBookmarksSequence = newBookmarks.recentBookmarks.asSequence()
val oldBookmarksList = this.recentBookmarks.asSequence()
return newBookmarksSequence.zip(oldBookmarksList).all { (new, old) ->
new == old
}
return newBookmarksSequence.zip(oldBookmarksList).all { (new, old) ->
new == old
}
}
}
data class HistoryMetadataItem(val historyMetadata: HistoryMetadata) : AdapterItem(
HistoryMetadataViewHolder.LAYOUT_ID

@ -317,7 +317,7 @@ class DefaultSessionControlController(
dismissSearchDialogIfDisplayed()
activity.openToBrowserAndLoad(
searchTermOrURL = SupportUtils.getGenericSumoURLForTopic
(SupportUtils.SumoTopic.PRIVATE_BROWSING_MYTHS),
(SupportUtils.SumoTopic.PRIVATE_BROWSING_MYTHS),
newTab = true,
from = BrowserDirection.FromHome
)
@ -401,9 +401,11 @@ class DefaultSessionControlController(
val searchAccessPoint = Event.PerformedSearch.SearchAccessPoint.TOPSITE
val event =
availableEngines.firstOrNull {
engine -> engine.resultUrls.firstOrNull { it.contains(url) } != null
engine ->
engine.resultUrls.firstOrNull { it.contains(url) } != null
}?.let {
searchEngine -> searchAccessPoint.let { sap ->
searchEngine ->
searchAccessPoint.let { sap ->
MetricsUtils.createSearchEvent(searchEngine, store, sap)
}
}
@ -424,7 +426,7 @@ class DefaultSessionControlController(
@VisibleForTesting
internal fun getAvailableSearchEngines() =
activity.components.core.store.state.search.searchEngines +
activity.components.core.store.state.search.availableSearchEngines
activity.components.core.store.state.search.availableSearchEngines
/**
* Append a search attribution query to any provided search engine URL based on the

@ -222,9 +222,16 @@ class SessionControlInteractor(
private val recentTabController: RecentTabController,
private val recentBookmarksController: RecentBookmarksController,
private val historyMetadataController: HistoryMetadataController
) : CollectionInteractor, OnboardingInteractor, TopSiteInteractor, TipInteractor,
TabSessionInteractor, ToolbarInteractor, ExperimentCardInteractor, RecentTabInteractor,
RecentBookmarksInteractor, HistoryMetadataInteractor {
) : CollectionInteractor,
OnboardingInteractor,
TopSiteInteractor,
TipInteractor,
TabSessionInteractor,
ToolbarInteractor,
ExperimentCardInteractor,
RecentTabInteractor,
RecentBookmarksInteractor,
HistoryMetadataInteractor {
override fun onCollectionAddTabTapped(collection: TabCollection) {
controller.handleCollectionAddTabTapped(collection)

@ -43,7 +43,7 @@ class OnboardingPrivateBrowsingViewHolder(
val text = SpannableString(view.context.getString(R.string.onboarding_private_browsing_description1)).apply {
val spanStartIndex = indexOf(IMAGE_PLACEHOLDER)
setSpan(
inlineIcon,
inlineIcon,
spanStartIndex,
spanStartIndex + IMAGE_PLACEHOLDER.length,
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE

@ -73,8 +73,8 @@ class BookmarkAdapter(private val emptyView: View, private val interactor: Bookm
override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean =
oldMode::class == newMode::class &&
old[oldItemPosition] in oldMode.selectedItems == new[newItemPosition] in newMode.selectedItems &&
old[oldItemPosition] == new[newItemPosition]
old[oldItemPosition] in oldMode.selectedItems == new[newItemPosition] in newMode.selectedItems &&
old[oldItemPosition] == new[newItemPosition]
override fun getChangePayload(oldItemPosition: Int, newItemPosition: Int): Any? {
val oldItem = old[oldItemPosition]

@ -43,6 +43,6 @@ class BookmarkDeselectNavigationListener(
*/
private fun differentFromSelectedFolder(arguments: Bundle?): Boolean {
return arguments != null &&
BookmarkFragmentArgs.fromBundle(arguments).currentRoot != viewModel.selectedFolder?.guid
BookmarkFragmentArgs.fromBundle(arguments).currentRoot != viewModel.selectedFolder?.guid
}
}

@ -295,10 +295,12 @@ class BookmarkFragment : LibraryPageFragment<BookmarkNode>(), UserInteractionHan
}
private fun deleteMulti(selected: Set<BookmarkNode>, eventType: Event = Event.RemoveBookmarks) {
selected.iterator().forEach { if (it.type == BookmarkNodeType.FOLDER) {
showRemoveFolderDialog(selected)
return
} }
selected.iterator().forEach {
if (it.type == BookmarkNodeType.FOLDER) {
showRemoveFolderDialog(selected)
return
}
}
updatePendingBookmarksToDelete(selected)
pendingBookmarkDeletionJob = getDeleteOperation(eventType)
@ -320,9 +322,11 @@ class BookmarkFragment : LibraryPageFragment<BookmarkNode>(), UserInteractionHan
viewLifecycleOwner.lifecycleScope.allowUndo(
requireView(), message,
getString(R.string.bookmark_undo_deletion), {
getString(R.string.bookmark_undo_deletion),
{
undoPendingDeletion(selected)
}, operation = getDeleteOperation(eventType)
},
operation = getDeleteOperation(eventType)
)
}

@ -89,8 +89,8 @@ private fun bookmarkFragmentStateReducer(
)
}
is BookmarkFragmentAction.Select -> state.copy(
mode = BookmarkFragmentState.Mode.Selecting(state.mode.selectedItems + action.item)
)
mode = BookmarkFragmentState.Mode.Selecting(state.mode.selectedItems + action.item)
)
is BookmarkFragmentAction.Deselect -> {
val items = state.mode.selectedItems - action.item
val mode = if (items.isEmpty()) {

@ -77,8 +77,12 @@ class SelectBookmarkFolderAdapter(private val sharedViewModel: BookmarksSharedVi
containerView.context,
R.drawable.ic_folder_icon
)?.apply {
setTint(ContextCompat.getColor(containerView.context,
R.color.primary_text_light_theme))
setTint(
ContextCompat.getColor(
containerView.context,
R.color.primary_text_light_theme
)
)
}
)
view.titleView.text = folder.node.title

@ -231,7 +231,8 @@ class DownloadFragment : LibraryPageFragment<DownloadItem>(), UserInteractionHan
String.format(
requireContext().getString(
R.string.download_delete_single_item_snackbar
), downloadItems.first().fileName
),
downloadItems.first().fileName
)
}
}

@ -122,9 +122,12 @@ class HistoryFragment : LibraryPageFragment<HistoryItem>(), UserInteractionHandl
requireComponents.core.historyStorage.createSynchronousPagedHistoryProvider()
)
viewModel.userHasHistory.observe(this, Observer {
historyView.updateEmptyState(it)
})
viewModel.userHasHistory.observe(
this,
Observer {
historyView.updateEmptyState(it)
}
)
requireComponents.analytics.metrics.track(Event.HistoryOpened)
@ -154,9 +157,12 @@ class HistoryFragment : LibraryPageFragment<HistoryItem>(), UserInteractionHandl
historyView.update(it)
}
viewModel.history.observe(viewLifecycleOwner, Observer {
historyView.historyAdapter.submitList(it)
})
viewModel.history.observe(
viewLifecycleOwner,
Observer {
historyView.historyAdapter.submitList(it)
}
)
}
override fun onResume() {
@ -229,7 +235,8 @@ class HistoryFragment : LibraryPageFragment<HistoryItem>(), UserInteractionHandl
String.format(
requireContext().getString(
R.string.history_delete_single_item_snackbar
), historyItems.first().url.toShortUrl(requireComponents.publicSuffixList)
),
historyItems.first().url.toShortUrl(requireComponents.publicSuffixList)
)
}
}

@ -175,7 +175,8 @@ class HistoryView(
view.context.getString(
if (numRecentTabs == 1)
R.string.recently_closed_tab else R.string.recently_closed_tabs
), numRecentTabs
),
numRecentTabs
)
isVisible = !userHasHistory
}

@ -116,7 +116,8 @@ class HistoryListItemViewHolder(
itemView.context.getString(
if (numRecentTabs == 1)
R.string.recently_closed_tab else R.string.recently_closed_tabs
), numRecentTabs
),
numRecentTabs
)
itemView.findViewById<ConstraintLayout>(R.id.recently_closed_nav).run {
if (isNormalMode) {

@ -62,9 +62,11 @@ class DefaultBrowserNotificationWorker(
return NotificationCompat.Builder(this, channelId)
.setSmallIcon(R.drawable.ic_status_logo)
.setContentTitle(
applicationContext.getString(R.string.notification_default_browser_title, appName))
applicationContext.getString(R.string.notification_default_browser_title, appName)
)
.setContentText(
applicationContext.getString(R.string.notification_default_browser_text, appName))
applicationContext.getString(R.string.notification_default_browser_text, appName)
)
.setBadgeIconType(NotificationCompat.BADGE_ICON_SMALL)
.setColor(ContextCompat.getColor(this, R.color.primary_text_light_theme))
.setPriority(NotificationCompat.PRIORITY_DEFAULT)

@ -49,7 +49,7 @@ object Performance {
val batteryStatus = context.registerReceiver(null, IntentFilter(Intent.ACTION_BATTERY_CHANGED))
batteryStatus?.let {
val isPhonePlugged = it.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1) ==
BatteryManager.BATTERY_PLUGGED_USB
BatteryManager.BATTERY_PLUGGED_USB
val isAdbEnabled = AndroidSettings.Global.getInt(
context.contentResolver,
AndroidSettings.Global.ADB_ENABLED, 0

@ -15,9 +15,9 @@ import java.lang.reflect.Modifier.PRIVATE
import java.util.concurrent.atomic.AtomicInteger
private val classPrefixList = arrayOf(
"android.widget.",
"android.webkit.",
"android.app."
"android.widget.",
"android.webkit.",
"android.app."
)
/**
* Counts the number of inflations fenix does. This class behaves only as an inflation counter since

@ -52,13 +52,15 @@ class StartupActivityLog {
return
}
val transformedEntries = log.map { when (it) {
is LogEntry.AppStarted -> "App-STARTED"
is LogEntry.AppStopped -> "App-STOPPED"
is LogEntry.ActivityCreated -> "${it.activityClass.simpleName}-CREATED"
is LogEntry.ActivityStarted -> "${it.activityClass.simpleName}-STARTED"
is LogEntry.ActivityStopped -> "${it.activityClass.simpleName}-STOPPED"
} }
val transformedEntries = log.map {
when (it) {
is LogEntry.AppStarted -> "App-STARTED"
is LogEntry.AppStopped -> "App-STOPPED"
is LogEntry.ActivityCreated -> "${it.activityClass.simpleName}-CREATED"
is LogEntry.ActivityStarted -> "${it.activityClass.simpleName}-STARTED"
is LogEntry.ActivityStopped -> "${it.activityClass.simpleName}-STOPPED"
}
}
loggerArg.debug(transformedEntries.toString())
}

@ -33,7 +33,8 @@ class StartupReportFullyDrawn {
*/
fun onActivityCreateEndHome(state: StartupState, activity: HomeActivity) {
if (!isInstrumented &&
state is StartupState.Cold && state.destination == APP_LINK) {
state is StartupState.Cold && state.destination == APP_LINK
) {
// Instrumenting the first frame drawn should be good enough for app link for now.
isInstrumented = true
attachReportFullyDrawn(activity, activity.findViewById(R.id.rootContainer))
@ -50,7 +51,8 @@ class StartupReportFullyDrawn {
*/
fun onTopSitesItemBound(state: StartupState, holder: TopSiteItemViewHolder) {
if (!isInstrumented &&
state is StartupState.Cold && state.destination == HOMESCREEN) {
state is StartupState.Cold && state.destination == HOMESCREEN
) {
isInstrumented = true
// Ideally we wouldn't cast to HomeActivity but we want to save implementation time.

@ -25,9 +25,12 @@ class VisualCompletenessQueue(val queue: RunWhenReadyQueue) {
containerWeakReference.get()?.doOnPreDraw {
// This delay is temporary. We are delaying 5 seconds until the performance
// team can locate the real point of visual completeness.
it.postDelayed({
queue.ready()
}, delay)
it.postDelayed(
{
queue.ready()
},
delay
)
}
}
}

@ -81,7 +81,8 @@ internal class WebPushEngineDelegate(
},
onSubscribe = { subscription ->
onSubscribe(subscription.toEnginePushSubscription())
})
}
)
}
override fun onUnsubscribe(scope: String, onUnsubscribe: (Boolean) -> Unit) {
@ -93,7 +94,8 @@ internal class WebPushEngineDelegate(
},
onUnsubscribe = { result ->
onUnsubscribe(result)
})
}
)
}
}

@ -132,15 +132,15 @@ class SearchDialogController(
fragmentStore.dispatch(
SearchFragmentAction.ShowSearchShortcutEnginePicker(
(textMatchesCurrentUrl || textMatchesCurrentSearch || text.isEmpty()) &&
settings.shouldShowSearchShortcuts
settings.shouldShowSearchShortcuts
)
)
fragmentStore.dispatch(
SearchFragmentAction.AllowSearchSuggestionsInPrivateModePrompt(
text.isNotEmpty() &&
activity.browsingModeManager.mode.isPrivate &&
!settings.shouldShowSearchSuggestionsInPrivate &&
!settings.showSearchSuggestionsInPrivateOnboardingFinished
activity.browsingModeManager.mode.isPrivate &&
!settings.shouldShowSearchSuggestionsInPrivate &&
!settings.showSearchSuggestionsInPrivateOnboardingFinished
)
)
}
@ -244,7 +244,7 @@ class SearchDialogController(
dismissDialog()
}
setPositiveButton(R.string.camera_permissions_needed_positive_button_text) {
dialog: DialogInterface, _ ->
dialog: DialogInterface, _ ->
val intent: Intent = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
Intent(android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
} else {

@ -508,8 +508,8 @@ class SearchDialogFragment : AppCompatDialogFragment(), UserInteractionHandler {
private fun updateSearchSuggestionsHintVisibility(state: SearchFragmentState) {
view?.apply {
val showHint = state.showSearchSuggestionsHint &&
!state.showSearchShortcuts &&
state.url != state.query
!state.showSearchShortcuts &&
state.url != state.query
findViewById<View>(R.id.search_suggestions_hint)?.isVisible = showHint
search_suggestions_hint_divider?.isVisible = showHint
@ -522,8 +522,8 @@ class SearchDialogFragment : AppCompatDialogFragment(), UserInteractionHandler {
val isVisible =
searchEngine?.id?.contains("google") == true &&
isSpeechAvailable() &&
requireContext().settings().shouldShowVoiceSearch
isSpeechAvailable() &&
requireContext().settings().shouldShowVoiceSearch
if (isVisible) {
toolbarView.view.addEditAction(
@ -559,8 +559,8 @@ class SearchDialogFragment : AppCompatDialogFragment(), UserInteractionHandler {
private fun updateClipboardSuggestion(searchState: SearchFragmentState, clipboardUrl: String?) {
val shouldShowView = searchState.showClipboardSuggestions &&
searchState.query.isEmpty() &&
!clipboardUrl.isNullOrEmpty() && !searchState.showSearchShortcuts
searchState.query.isEmpty() &&
!clipboardUrl.isNullOrEmpty() && !searchState.showSearchShortcuts
fill_link_from_clipboard.isVisible = shouldShowView
fill_link_divider.isVisible = shouldShowView

@ -34,9 +34,9 @@ class PerformanceActivityLifecycleCallbacks(
// They have been whitelisted in case new activities are added to the application
// to ensure these new activities would not crash the application.
return isTransientActivityInMigrationVariant(activity) ||
(activity is IntentReceiverActivity) ||
(activity is VoiceSearchActivity) ||
(activity is AuthIntentReceiverActivity)
(activity is IntentReceiverActivity) ||
(activity is VoiceSearchActivity) ||
(activity is AuthIntentReceiverActivity)
}
/**

@ -116,16 +116,20 @@ class CustomizationFragment : PreferenceFragmentCompat() {
private fun setupToolbarCategory() {
val topPreference = requirePreference<RadioButtonPreference>(R.string.pref_key_toolbar_top)
topPreference.onClickListener {
requireContext().components.analytics.metrics.track(Event.ToolbarPositionChanged(
Event.ToolbarPositionChanged.Position.TOP
))
requireContext().components.analytics.metrics.track(
Event.ToolbarPositionChanged(
Event.ToolbarPositionChanged.Position.TOP
)
)
}
val bottomPreference = requirePreference<RadioButtonPreference>(R.string.pref_key_toolbar_bottom)
bottomPreference.onClickListener {
requireContext().components.analytics.metrics.track(Event.ToolbarPositionChanged(
Event.ToolbarPositionChanged.Position.BOTTOM
))
requireContext().components.analytics.metrics.track(
Event.ToolbarPositionChanged(
Event.ToolbarPositionChanged.Position.BOTTOM
)
)
}
val toolbarPosition = requireContext().settings().toolbarPosition

@ -20,8 +20,10 @@ fun SitePermissions.toggle(featurePhone: PhoneFeature): SitePermissions {
fun SitePermissions.get(field: PhoneFeature) = when (field) {
PhoneFeature.AUTOPLAY ->
throw IllegalAccessException("AUTOPLAY can't be accessed via get try " +
"using AUTOPLAY_AUDIBLE and AUTOPLAY_INAUDIBLE")
throw IllegalAccessException(
"AUTOPLAY can't be accessed via get try " +
"using AUTOPLAY_AUDIBLE and AUTOPLAY_INAUDIBLE"
)
PhoneFeature.CAMERA -> camera
PhoneFeature.LOCATION -> location
PhoneFeature.MICROPHONE -> microphone
@ -33,8 +35,10 @@ fun SitePermissions.get(field: PhoneFeature) = when (field) {
}
fun SitePermissions.update(field: PhoneFeature, value: SitePermissions.Status) = when (field) {
PhoneFeature.AUTOPLAY -> throw IllegalAccessException("AUTOPLAY can't be accessed via update " +
"try using AUTOPLAY_AUDIBLE and AUTOPLAY_INAUDIBLE")
PhoneFeature.AUTOPLAY -> throw IllegalAccessException(
"AUTOPLAY can't be accessed via update " +
"try using AUTOPLAY_AUDIBLE and AUTOPLAY_INAUDIBLE"
)
PhoneFeature.CAMERA -> copy(camera = value)
PhoneFeature.LOCATION -> copy(location = value)
PhoneFeature.MICROPHONE -> copy(microphone = value)

@ -71,7 +71,8 @@ class PairFragment : Fragment(R.layout.fragment_pair), UserInteractionHandler {
},
scanMessage =
if (requireContext().settings().allowDomesticChinaFxaServer &&
org.mozilla.fenix.Config.channel.isMozillaOnline)
org.mozilla.fenix.Config.channel.isMozillaOnline
)
R.string.pair_instructions_2_cn
else R.string.pair_instructions_2
),

@ -55,7 +55,8 @@ private fun DebugInfo() {
)
Text(
text = store.state.search.region?.home ?: "Unknown",
modifier = Modifier.padding(4.dp))
modifier = Modifier.padding(4.dp)
)
Text(
text = stringResource(R.string.debug_info_region_current),
style = MaterialTheme.typography.h6,

@ -370,9 +370,12 @@ class SettingsFragment : PreferenceFragmentCompat() {
Toast.LENGTH_LONG
).show()
Handler(Looper.getMainLooper()).postDelayed({
exitProcess(0)
}, AMO_COLLECTION_OVERRIDE_EXIT_DELAY)
Handler(Looper.getMainLooper()).postDelayed(
{
exitProcess(0)
},
AMO_COLLECTION_OVERRIDE_EXIT_DELAY
)
}
binding.customAmoCollection.setText(context.settings().overrideAmoCollection)
@ -435,9 +438,12 @@ class SettingsFragment : PreferenceFragmentCompat() {
getString(R.string.toast_override_fxa_sync_server_done),
Toast.LENGTH_LONG
).show()
Handler(Looper.getMainLooper()).postDelayed({
exitProcess(0)
}, FXA_SYNC_OVERRIDE_EXIT_DELAY)
Handler(Looper.getMainLooper()).postDelayed(
{
exitProcess(0)
},
FXA_SYNC_OVERRIDE_EXIT_DELAY
)
}
}
}
@ -538,8 +544,8 @@ class SettingsFragment : PreferenceFragmentCompat() {
findPreference<Preference>(getPreferenceKey(R.string.pref_key_override_sync_tokenserver))
val settings = requireContext().settings()
val show = settings.overrideFxAServer.isNotEmpty() ||
settings.overrideSyncTokenServer.isNotEmpty() ||
settings.showSecretDebugMenuThisSession
settings.overrideSyncTokenServer.isNotEmpty() ||
settings.showSecretDebugMenuThisSession
// Only enable changes to these prefs when the user isn't connected to an account.
val enabled =
requireComponents.backgroundServices.accountManager.authenticatedAccount() == null
@ -560,9 +566,11 @@ class SettingsFragment : PreferenceFragmentCompat() {
val preferenceAmoCollectionOverride =
findPreference<Preference>(getPreferenceKey(R.string.pref_key_override_amo_collection))
val show = (Config.channel.isNightlyOrDebug && (
settings.amoCollectionOverrideConfigured() || settings.showSecretDebugMenuThisSession)
)
val show = (
Config.channel.isNightlyOrDebug && (
settings.amoCollectionOverrideConfigured() || settings.showSecretDebugMenuThisSession
)
)
preferenceAmoCollectionOverride?.apply {
isVisible = show
summary = settings.overrideAmoCollection.ifEmpty { null }
@ -589,9 +597,12 @@ class SettingsFragment : PreferenceFragmentCompat() {
getString(R.string.toast_override_fxa_sync_server_done),
Toast.LENGTH_LONG
).show()
Handler(Looper.getMainLooper()).postDelayed({
exitProcess(0)
}, FXA_SYNC_OVERRIDE_EXIT_DELAY)
Handler(Looper.getMainLooper()).postDelayed(
{
exitProcess(0)
},
FXA_SYNC_OVERRIDE_EXIT_DELAY
)
}
}
}

@ -29,11 +29,11 @@ object SupportUtils {
const val GOOGLE_URL = "https://www.google.com/"
const val BAIDU_URL = "https://m.baidu.com/?from=1000969a"
const val JD_URL = "https://union-click.jd.com/jdc" +
"?e=&p=AyIGZRprFDJWWA1FBCVbV0IUWVALHFRBEwQAQB1AWQkFVUVXfFkAF14lRFRbJXstVWR3WQ1rJ08AZnhS" +
"HDJBYh4LZR9eEAMUBlccWCUBEQZRGFoXCxc3ZRteJUl8BmUZWhQ" +
"AEwdRGF0cMhIAVB5ZFAETBVAaXRwyFQdcKydLSUpaCEtYFAIXN2UrWCUyIgdVK1slXVZaCCtZFAMWDg%3D%3D"
"?e=&p=AyIGZRprFDJWWA1FBCVbV0IUWVALHFRBEwQAQB1AWQkFVUVXfFkAF14lRFRbJXstVWR3WQ1rJ08AZnhS" +
"HDJBYh4LZR9eEAMUBlccWCUBEQZRGFoXCxc3ZRteJUl8BmUZWhQ" +
"AEwdRGF0cMhIAVB5ZFAETBVAaXRwyFQdcKydLSUpaCEtYFAIXN2UrWCUyIgdVK1slXVZaCCtZFAMWDg%3D%3D"
const val PDD_URL = "https://mobile.yangkeduo.com/duo_cms_mall.html?pid=13289095_194240604&" +
"cpsSign=CM_210309_13289095_194240604_8bcfd56d5db3c43d983014d2658ec26e&duoduo_type=2"
"cpsSign=CM_210309_13289095_194240604_8bcfd56d5db3c43d983014d2658ec26e&duoduo_type=2"
const val GOOGLE_US_URL = "https://www.google.com/webhp?client=firefox-b-1-m&channel=ts"
const val GOOGLE_XX_URL = "https://www.google.com/webhp?client=firefox-b-m&channel=ts"

@ -44,19 +44,22 @@ class SyncPreferenceView(
) {
init {
accountManager.register(object : AccountObserver {
override fun onAuthenticated(account: OAuthAccount, authType: AuthType) {
MainScope().launch { updateSyncPreferenceStatus() }
}
override fun onLoggedOut() {
MainScope().launch { updateSyncPreferenceNeedsLogin() }
}
override fun onAuthenticationProblems() {
MainScope().launch { updateSyncPreferenceNeedsReauth() }
}
}, owner = lifecycleOwner)
accountManager.register(
object : AccountObserver {
override fun onAuthenticated(account: OAuthAccount, authType: AuthType) {
MainScope().launch { updateSyncPreferenceStatus() }
}
override fun onLoggedOut() {
MainScope().launch { updateSyncPreferenceNeedsLogin() }
}
override fun onAuthenticationProblems() {
MainScope().launch { updateSyncPreferenceNeedsReauth() }
}
},
owner = lifecycleOwner
)
val accountExists = accountManager.authenticatedAccount() != null
val needsReauth = accountManager.accountNeedsReauth()

@ -353,23 +353,23 @@ class TextPercentageSeekBarPreference @JvmOverloads constructor(
}
mSeekBar?.setAccessibilityDelegate(object :
View.AccessibilityDelegate() {
override fun onInitializeAccessibilityNodeInfo(
host: View?,
info: AccessibilityNodeInfo?
) {
super.onInitializeAccessibilityNodeInfo(host, info)
val initialInfo = info?.rangeInfo
info?.rangeInfo = initialInfo?.let {
AccessibilityNodeInfo.RangeInfo.obtain(
RANGE_TYPE_PERCENT,
MIN_VALUE.toFloat(),
SEEK_BAR_MAX.toFloat(),
convertCurrentValue(it.current)
)
View.AccessibilityDelegate() {
override fun onInitializeAccessibilityNodeInfo(
host: View?,
info: AccessibilityNodeInfo?
) {
super.onInitializeAccessibilityNodeInfo(host, info)
val initialInfo = info?.rangeInfo
info?.rangeInfo = initialInfo?.let {
AccessibilityNodeInfo.RangeInfo.obtain(
RANGE_TYPE_PERCENT,
MIN_VALUE.toFloat(),
SEEK_BAR_MAX.toFloat(),
convertCurrentValue(it.current)
)
}
}
}
})
})
}
/**

@ -76,7 +76,7 @@ class TrackingProtectionFragment : PreferenceFragmentCompat() {
learnMorePreference.setOnPreferenceClickListener {
(activity as HomeActivity).openToBrowserAndLoad(
searchTermOrURL = SupportUtils.getGenericSumoURLForTopic
(SupportUtils.SumoTopic.TRACKING_PROTECTION),
(SupportUtils.SumoTopic.TRACKING_PROTECTION),
newTab = true,
from = BrowserDirection.FromTrackingProtection
)

@ -138,13 +138,15 @@ class AboutFragment : Fragment(), AboutPageListener {
AboutItem.ExternalLink(
WHATS_NEW,
SupportUtils.getWhatsNewUrl(context)
), getString(R.string.about_whats_new, getString(R.string.app_name))
),
getString(R.string.about_whats_new, getString(R.string.app_name))
),
AboutPageItem(
AboutItem.ExternalLink(
SUPPORT,
SupportUtils.getSumoURLForTopic(context, SupportUtils.SumoTopic.HELP)
), getString(R.string.about_support)
),
getString(R.string.about_support)
),
AboutPageItem(
AboutItem.Crashes,
@ -154,13 +156,15 @@ class AboutFragment : Fragment(), AboutPageListener {
AboutItem.ExternalLink(
PRIVACY_NOTICE,
SupportUtils.getMozillaPageUrl(SupportUtils.MozillaPage.PRIVATE_NOTICE)
), getString(R.string.about_privacy_notice)
),
getString(R.string.about_privacy_notice)
),
AboutPageItem(
AboutItem.ExternalLink(
RIGHTS,
SupportUtils.getSumoURLForTopic(context, SupportUtils.SumoTopic.YOUR_RIGHTS)
), getString(R.string.about_know_your_rights)
),
getString(R.string.about_know_your_rights)
),
AboutPageItem(
AboutItem.ExternalLink(LICENSING_INFO, ABOUT_LICENSE_URL),

@ -24,7 +24,8 @@ class DefaultLocaleSettingsController(
override fun handleLocaleSelected(locale: Locale) {
if (localeSettingsStore.state.selectedLocale == locale &&
!LocaleManager.isDefaultLocaleSelected(activity)) {
!LocaleManager.isDefaultLocaleSelected(activity)
) {
return
}
localeSettingsStore.dispatch(LocaleSettingsAction.Select(locale))

@ -17,14 +17,18 @@ fun LocaleManager.getSupportedLocales(): List<Locale> {
val resultLocaleList: MutableList<Locale> = ArrayList()
resultLocaleList.add(0, getSystemDefault())
resultLocaleList.addAll(BuildConfig.SUPPORTED_LOCALE_ARRAY
.toList()
.map {
it.toLocale()
}.sortedWith(compareBy(
{ it.displayLanguage },
{ it.displayCountry }
)))
resultLocaleList.addAll(
BuildConfig.SUPPORTED_LOCALE_ARRAY
.toList()
.map {
it.toLocale()
}.sortedWith(
compareBy(
{ it.displayLanguage },
{ it.displayCountry }
)
)
)
return resultLocaleList
}

@ -64,8 +64,8 @@ private fun localeSettingsStateReducer(
is LocaleSettingsAction.Search -> {
val searchedItems = state.localeList.filter {
it.getDisplayLanguage(it).startsWith(action.query, ignoreCase = true) ||
it.displayLanguage.startsWith(action.query, ignoreCase = true) ||
it === state.localeList[0]
it.displayLanguage.startsWith(action.query, ignoreCase = true) ||
it === state.localeList[0]
}
state.copy(searchedLocaleList = searchedItems)
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save