Skip to content
This repository has been archived by the owner on Feb 20, 2023. It is now read-only.

Commit

Permalink
For #4118 - Creates setting for auto closing tabs
Browse files Browse the repository at this point in the history
  • Loading branch information
ekager committed Sep 1, 2020
1 parent 7c7aa46 commit 2d67e4b
Show file tree
Hide file tree
Showing 18 changed files with 358 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ class SettingsBasicsTest {
verifyBasicsHeading()
verifySearchEngineButton()
verifyDefaultBrowserItem()
verifyCloseTabsItem()
// drill down to submenu
}.openSearchSubMenu {
verifyDefaultSearchEngineHeader()
Expand Down Expand Up @@ -168,6 +169,17 @@ class SettingsBasicsTest {
}
}

@Test
fun changeCloseTabsSetting() {
// Goes through the settings and verified the close tabs setting options.
homeScreen {
}.openThreeDotMenu {
}.openSettings {
}.openCloseTabsSubMenu {
verifyOptions()
}
}

@Test
fun changeAccessibiltySettings() {
// Goes through the settings and changes the default text on a webpage, then verifies if the text has changed.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ class SettingsRobot {
fun verifyAccessibilityButton() = assertAccessibilityButton()
fun verifySetAsDefaultBrowserButton() = assertSetAsDefaultBrowserButton()
fun verifyDefaultBrowserItem() = assertDefaultBrowserItem()
fun verifyCloseTabsItem() = assertCloseTabsItem()
fun verifyDefaultBrowserIsDisaled() = assertDefaultBrowserIsDisabled()
fun clickDefaultBrowserSwitch() = toggleDefaultBrowserSwitch()
fun verifyAndroidDefaultAppsMenuAppears() = assertAndroidDefaultAppsMenuAppears()
Expand Down Expand Up @@ -134,6 +135,15 @@ class SettingsRobot {
return SettingsSubMenuThemeRobot.Transition()
}

fun openCloseTabsSubMenu(interact: SettingsSubMenuTabsRobot.() -> Unit): SettingsSubMenuTabsRobot.Transition {

fun closeTabsButton() = onView(withText("Close tabs"))
closeTabsButton().click()

SettingsSubMenuTabsRobot().interact()
return SettingsSubMenuTabsRobot.Transition()
}

fun openAccessibilitySubMenu(interact: SettingsSubMenuAccessibilityRobot.() -> Unit): SettingsSubMenuAccessibilityRobot.Transition {

fun accessibilityButton() = onView(withText("Accessibility"))
Expand Down Expand Up @@ -237,8 +247,11 @@ private fun assertSettingsView() {
}

// GENERAL SECTION
private fun assertGeneralHeading() = onView(withText("General"))
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
private fun assertGeneralHeading() {
scrollToElementByText("General")
onView(withText("General"))
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
}

private fun assertSearchEngineButton() {
mDevice.wait(Until.findObject(By.text("Search")), waitingTime)
Expand Down Expand Up @@ -284,8 +297,15 @@ private fun assertDefaultBrowserItem() {
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
}

private fun assertCloseTabsItem() {
mDevice.wait(Until.findObject(By.text("Close tabs")), waitingTime)
onView(withText("Close tabs"))
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
}

// PRIVACY SECTION
private fun assertPrivacyHeading() {
scrollToElementByText("Privacy and security")
onView(withText("Privacy and security"))
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/* 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/. */

@file:Suppress("TooManyFunctions")

package org.mozilla.fenix.ui.robots

import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.action.ViewActions
import androidx.test.espresso.assertion.ViewAssertions
import androidx.test.espresso.matcher.ViewMatchers
import androidx.test.espresso.matcher.ViewMatchers.withText
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.uiautomator.UiDevice
import org.hamcrest.CoreMatchers.allOf

/**
* Implementation of Robot Pattern for the settings Tabs sub menu.
*/
class SettingsSubMenuTabsRobot {

fun verifyOptions() = assertOptions()

class Transition {
val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())

fun goBack(interact: SettingsRobot.() -> Unit): SettingsRobot.Transition {
mDevice.waitForIdle()
goBackButton().perform(ViewActions.click())

SettingsRobot().interact()
return SettingsRobot.Transition()
}
}
}

private fun assertOptions() {
afterOneDayToggle()
.check(ViewAssertions.matches(ViewMatchers.withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
manualToggle()
.check(ViewAssertions.matches(ViewMatchers.withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
afterOneWeekToggle()
.check(ViewAssertions.matches(ViewMatchers.withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
afterOneMonthToggle()
.check(ViewAssertions.matches(ViewMatchers.withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
}

private fun manualToggle() = onView(withText("Manually"))

private fun afterOneDayToggle() = onView(withText("After one day"))

private fun afterOneWeekToggle() = onView(withText("After one week"))

private fun afterOneMonthToggle() = onView(withText("After one month"))

private fun goBackButton() =
onView(allOf(ViewMatchers.withContentDescription("Navigate up")))
8 changes: 8 additions & 0 deletions app/src/main/java/org/mozilla/fenix/HomeActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,14 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity {
}

settings().wasDefaultBrowserOnLastResume = settings().isDefaultBrowser()

if (!settings().manuallyCloseTabs) {
components.core.store.state.tabs.filter {
(System.currentTimeMillis() - it.lastAccess) > settings().getTabTimeout()
}.forEach {
components.useCases.tabsUseCases.removeTab(it.id)
}
}
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/* 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.settings

import android.os.Bundle
import androidx.preference.PreferenceFragmentCompat
import org.mozilla.fenix.R
import org.mozilla.fenix.ext.showToolbar
import org.mozilla.fenix.utils.view.addToRadioGroup

/**
* Lets the user customize auto closing tabs.
*/
class CloseTabsSettingsFragment : PreferenceFragmentCompat() {
private lateinit var radioManual: RadioButtonPreference
private lateinit var radioOneDay: RadioButtonPreference
private lateinit var radioOneWeek: RadioButtonPreference
private lateinit var radioOneMonth: RadioButtonPreference

override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
setPreferencesFromResource(R.xml.close_tabs_preferences, rootKey)
}

override fun onResume() {
super.onResume()
showToolbar(getString(R.string.preferences_close_tabs))
setupPreferences()
}

private fun setupPreferences() {
radioManual = requirePreference(R.string.pref_key_close_tabs_manually)
radioOneDay = requirePreference(R.string.pref_key_close_tabs_after_one_day)
radioOneWeek = requirePreference(R.string.pref_key_close_tabs_after_one_week)
radioOneMonth = requirePreference(R.string.pref_key_close_tabs_after_one_month)
setupRadioGroups()
}

private fun setupRadioGroups() {
addToRadioGroup(
radioManual,
radioOneDay,
radioOneMonth,
radioOneWeek
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,10 @@ class SettingsFragment : PreferenceFragmentCompat() {
}
}

val tabSettingsPreference =
requirePreference<Preference>(R.string.pref_key_close_tabs)
tabSettingsPreference.summary = context?.settings()?.getTabTimeoutString()

setupPreferences()

if (shouldUpdateAccountUIState) {
Expand All @@ -192,6 +196,9 @@ class SettingsFragment : PreferenceFragmentCompat() {
resources.getString(R.string.pref_key_sign_in) -> {
SettingsFragmentDirections.actionSettingsFragmentToTurnOnSyncFragment()
}
resources.getString(R.string.pref_key_close_tabs) -> {
SettingsFragmentDirections.actionSettingsFragmentToCloseTabsSettingsFragment()
}
resources.getString(R.string.pref_key_search_settings) -> {
SettingsFragmentDirections.actionSettingsFragmentToSearchEngineFragment()
}
Expand Down Expand Up @@ -301,7 +308,8 @@ class SettingsFragment : PreferenceFragmentCompat() {
requirePreference<Preference>(R.string.pref_key_external_download_manager)
val preferenceLeakCanary = findPreference<Preference>(leakKey)
val preferenceRemoteDebugging = findPreference<Preference>(debuggingKey)
val preferenceMakeDefaultBrowser = requirePreference<Preference>(R.string.pref_key_make_default_browser)
val preferenceMakeDefaultBrowser =
requirePreference<Preference>(R.string.pref_key_make_default_browser)

if (!Config.channel.isReleased) {
preferenceLeakCanary?.setOnPreferenceChangeListener { _, newValue ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import org.mozilla.fenix.home.HomeFragment
interface TabTrayController {
fun onNewTabTapped(private: Boolean)
fun onTabTrayDismissed()
fun handleTabSettingsClicked()
fun onShareTabsClicked(private: Boolean)
fun onSyncedTabClicked(syncTab: SyncTab)
fun onSaveToCollectionClicked(selectedTabs: Set<Tab>)
Expand Down Expand Up @@ -88,6 +89,10 @@ class DefaultTabTrayController(
)
}

override fun handleTabSettingsClicked() {
navController.navigate(TabTrayDialogFragmentDirections.actionGlobalCloseTabSettingsFragment())
}

override fun onTabTrayDismissed() {
dismissTabTray()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ interface TabTrayInteractor {
*/
fun onShareTabsClicked(private: Boolean)

/**
* Called when user clicks the tab settings button.
*/
fun onTabSettingsClicked()

/**
* Called when user clicks button to save selected tabs to a collection.
*/
Expand Down Expand Up @@ -83,6 +88,10 @@ class TabTrayFragmentInteractor(private val controller: TabTrayController) : Tab
controller.onTabTrayDismissed()
}

override fun onTabSettingsClicked() {
controller.handleTabSettingsClicked()
}

override fun onShareTabsClicked(private: Boolean) {
controller.onShareTabsClicked(private)
}
Expand Down
9 changes: 9 additions & 0 deletions app/src/main/java/org/mozilla/fenix/tabtray/TabTrayView.kt
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@ class TabTrayView(
is TabTrayItemMenu.Item.ShareAllTabs -> interactor.onShareTabsClicked(
isPrivateModeSelected
)
is TabTrayItemMenu.Item.OpenTabSettings -> interactor.onTabSettingsClicked()
is TabTrayItemMenu.Item.SaveToCollection -> interactor.onEnterMultiselect()
is TabTrayItemMenu.Item.CloseAllTabs -> interactor.onCloseAllTabsClicked(
isPrivateModeSelected
Expand Down Expand Up @@ -574,6 +575,7 @@ class TabTrayItemMenu(

sealed class Item {
object ShareAllTabs : Item()
object OpenTabSettings : Item()
object SaveToCollection : Item()
object CloseAllTabs : Item()
}
Expand All @@ -598,6 +600,13 @@ class TabTrayItemMenu(
onItemTapped.invoke(Item.ShareAllTabs)
},

SimpleBrowserMenuItem(
context.getString(R.string.tab_tray_menu_tab_settings),
textColorResource = R.color.primary_text_normal_theme
) {
onItemTapped.invoke(Item.OpenTabSettings)
},

SimpleBrowserMenuItem(
context.getString(R.string.tab_tray_menu_item_close),
textColorResource = R.color.primary_text_normal_theme
Expand Down
46 changes: 46 additions & 0 deletions app/src/main/java/org/mozilla/fenix/utils/Settings.kt
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ class Settings(private val appContext: Context) : PreferencesHolder {
private const val CFR_COUNT_CONDITION_FOCUS_NOT_INSTALLED = 3
private const val MIN_DAYS_SINCE_FEEDBACK_PROMPT = 120

const val ONE_DAY_MS = 60 * 60 * 24 * 1000L
const val ONE_WEEK_MS = 60 * 60 * 24 * 7 * 1000L
const val ONE_MONTH_MS = (60 * 60 * 24 * 365 * 1000L) / 12

private fun Action.toInt() = when (this) {
Action.BLOCKED -> BLOCKED_INT
Action.ASK_TO_ALLOW -> ASK_TO_ALLOW_INT
Expand Down Expand Up @@ -324,6 +328,48 @@ class Settings(private val appContext: Context) : PreferencesHolder {
default = false
)

var manuallyCloseTabs by booleanPreference(
appContext.getPreferenceKey(R.string.pref_key_close_tabs_manually),
default = true
)

var closeTabsAfterOneDay by booleanPreference(
appContext.getPreferenceKey(R.string.pref_key_close_tabs_after_one_day),
default = false
)

var closeTabsAfterOneWeek by booleanPreference(
appContext.getPreferenceKey(R.string.pref_key_close_tabs_after_one_week),
default = false
)

var closeTabsAfterOneMonth by booleanPreference(
appContext.getPreferenceKey(R.string.pref_key_close_tabs_after_one_month),
default = false
)

fun getTabTimeout(): Long = when {
closeTabsAfterOneDay -> ONE_DAY_MS
closeTabsAfterOneWeek -> ONE_WEEK_MS
closeTabsAfterOneMonth -> ONE_MONTH_MS
else -> System.currentTimeMillis()
}

fun getTabTimeoutString(): String = when {
closeTabsAfterOneDay -> {
appContext.getString(R.string.close_tabs_after_one_day)
}
closeTabsAfterOneWeek -> {
appContext.getString(R.string.close_tabs_after_one_week)
}
closeTabsAfterOneMonth -> {
appContext.getString(R.string.close_tabs_after_one_week)
}
else -> {
appContext.getString(R.string.close_tabs_manually)
}
}

val shouldUseDarkTheme by booleanPreference(
appContext.getPreferenceKey(R.string.pref_key_dark_theme),
default = false
Expand Down
13 changes: 13 additions & 0 deletions app/src/main/res/drawable/ic_multiple_tabs.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 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/. -->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M15.22 22H5.78A3.78 3.78 0 0 1 2 18.22V8.78C2 6.69 3.7 5 5.78 5h9.44C17.31 5 19 6.7 19 8.78v9.44c0 2-1.7 3.78-3.78 3.78zM5.86 7C4.83 7 4 7.83 4 8.86v9.28C4 19.17 4.83 20 5.86 20h9.28c1 0 1.86-0.83 1.86-1.86V8.86C17 8 16.17 7 15 7H6zM6 4c0-1.1 1-2 2-2h8a6 6 0 0 1 6 6v0L22 16a2 2 0 0 1-2 2L20 8V8a4 4 0 0 0-4-4H6z"
android:fillColor="?primaryText" />
</vector>
Loading

0 comments on commit 2d67e4b

Please sign in to comment.