Copione merged onto master
continuous-integration/drone/push Build is failing
Details
continuous-integration/drone/push Build is failing
Details
commit
d518f35c3e
|
@ -67,7 +67,9 @@ Before you attempt to make a contribution please read the [Community Participati
|
|||
|
||||
## Build Instructions
|
||||
|
||||
Note: Both Android SDK and NDK are required.
|
||||
Pre-requisites:
|
||||
* Android SDK
|
||||
* To run command line tools, you'll need to configure Java: see [our how-to guide](https://github.com/mozilla-mobile/shared-docs/blob/master/android/configure_java.md).
|
||||
|
||||
1. Clone or Download the repository:
|
||||
|
||||
|
@ -131,6 +133,9 @@ recommend you use our provided pre-push hook in `config/pre-push-recommended.sh`
|
|||
Using this hook will guarantee your hook gets updated as the repository changes.
|
||||
This hook tries to run as much as possible without taking too much time.
|
||||
|
||||
Before you can run the hook, you'll need to configure Java properly because it relies on command line tools: see
|
||||
[our how-to guide](https://github.com/mozilla-mobile/shared-docs/blob/master/android/configure_java.md).
|
||||
|
||||
To add it on Mac/Linux, run this command from the project root:
|
||||
```sh
|
||||
ln -s ../../config/pre-push-recommended.sh .git/hooks/pre-push
|
||||
|
|
|
@ -72,20 +72,6 @@ android {
|
|||
"sharedUserId": "org.mozilla.fenix.performancetest.sharedID"
|
||||
]
|
||||
}
|
||||
fenixNightly releaseTemplate >> {
|
||||
applicationIdSuffix ".fenix.nightly"
|
||||
buildConfigField "boolean", "USE_RELEASE_VERSIONING", "true"
|
||||
def deepLinkSchemeValue = "fenix-nightly"
|
||||
buildConfigField "String", "DEEP_LINK_SCHEME", "\"$deepLinkSchemeValue\""
|
||||
manifestPlaceholders = ["deepLinkScheme": deepLinkSchemeValue]
|
||||
}
|
||||
fenixBeta releaseTemplate >> {
|
||||
applicationIdSuffix ".fenix.beta"
|
||||
buildConfigField "boolean", "USE_RELEASE_VERSIONING", "true"
|
||||
def deepLinkSchemeValue = "fenix-beta"
|
||||
buildConfigField "String", "DEEP_LINK_SCHEME", "\"$deepLinkSchemeValue\""
|
||||
manifestPlaceholders = ["deepLinkScheme": deepLinkSchemeValue]
|
||||
}
|
||||
fenixProduction releaseTemplate >> {
|
||||
applicationIdSuffix ".fenix"
|
||||
buildConfigField "boolean", "USE_RELEASE_VERSIONING", "true"
|
||||
|
@ -127,23 +113,6 @@ android {
|
|||
"deepLinkScheme": deepLinkSchemeValue
|
||||
]
|
||||
}
|
||||
fennecNightly releaseTemplate >> {
|
||||
buildConfigField "boolean", "USE_RELEASE_VERSIONING", "true"
|
||||
applicationIdSuffix ".fennec_aurora"
|
||||
def deepLinkSchemeValue = "fenix-nightly"
|
||||
buildConfigField "String", "DEEP_LINK_SCHEME", "\"$deepLinkSchemeValue\""
|
||||
manifestPlaceholders = [
|
||||
// This release type is meant to replace Firefox (Release channel) and therefore needs to inherit
|
||||
// its sharedUserId for all eternity. See:
|
||||
// https://searchfox.org/mozilla-central/search?q=moz_android_shared_id&case=false®exp=false&path=
|
||||
// Shipping an app update without sharedUserId can have
|
||||
// fatal consequences. For example see:
|
||||
// - https://issuetracker.google.com/issues/36924841
|
||||
// - https://issuetracker.google.com/issues/36905922
|
||||
"sharedUserId": "org.mozilla.fennec.sharedID",
|
||||
"deepLinkScheme": deepLinkSchemeValue
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
variantFilter { // There's a "release" build type that exists by default that we don't use (it's replaced by "nightly" and "beta")
|
||||
|
@ -157,19 +126,12 @@ android {
|
|||
// |--------------------|---------------|-----------|
|
||||
// | debug | ✅ | ✅ | Both variants for testing and development.
|
||||
// | forPerformanceTest | ✅ | ✅ | Both variants unless the perf team only cares about Nightly (TBD).
|
||||
// | fenixNightly | ✅ | ✅ | Built with both, but only the "geckoNightly" one is published to Google Play
|
||||
// | fenixBeta | ❌ | ✅ | Fenix Beta ships with GV Beta
|
||||
// | fenixProduction | ❌ | ✅ | Fenix Production ships with GV Beta
|
||||
// | fenixProduction | ✅ | ❌ | Fenix Production (to be renamed `Nightly`) ships with GV Nightly
|
||||
// | fennecProduction | ❌ | ✅ | Fenix build to replace production Firefox builds
|
||||
// | fennecBeta | ❌ | ✅ | Fenix build to replace beta Firefox builds
|
||||
// | fennecNightly | ✅ | ❌ | Fenix build to replace Nightly Firefox builds
|
||||
|
||||
def flavors = flavors*.name.toString().toLowerCase()
|
||||
|
||||
if (buildType.name == 'fenixBeta' && flavors.contains("geckonightly")) {
|
||||
setIgnore true
|
||||
}
|
||||
|
||||
if (buildType.name == 'fenixProduction' && flavors.contains("geckobeta")) {
|
||||
setIgnore true
|
||||
}
|
||||
|
@ -177,10 +139,6 @@ android {
|
|||
if ((buildType.name == 'fennecProduction' || buildType.name == 'fennecBeta') && flavors.contains("geckonightly")) {
|
||||
setIgnore true
|
||||
}
|
||||
|
||||
if (buildType.name == 'fennecNightly' && flavors.contains("geckobeta")) {
|
||||
setIgnore true
|
||||
}
|
||||
}
|
||||
|
||||
aaptOptions {
|
||||
|
@ -207,10 +165,6 @@ android {
|
|||
androidTest {
|
||||
resources.srcDirs += ['src/androidTest/resources']
|
||||
}
|
||||
fennecNightly {
|
||||
java.srcDirs = ['src/migration/java']
|
||||
manifest.srcFile "src/migration/AndroidManifest.xml"
|
||||
}
|
||||
fennecBeta {
|
||||
java.srcDirs = ['src/migration/java']
|
||||
manifest.srcFile "src/migration/AndroidManifest.xml"
|
||||
|
|
|
@ -330,7 +330,10 @@ class BookmarksTest {
|
|||
createBookmark(defaultWebPage.url)
|
||||
}.openTabDrawer {
|
||||
closeTab()
|
||||
}.openHomeScreen { }.openThreeDotMenu {
|
||||
}
|
||||
|
||||
homeScreen {
|
||||
}.openThreeDotMenu {
|
||||
}.openBookmarks {
|
||||
bookmarksListIdlingResource =
|
||||
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.bookmark_list))
|
||||
|
|
|
@ -212,7 +212,9 @@ class HistoryTest {
|
|||
mDevice.waitForIdle()
|
||||
}.openTabDrawer {
|
||||
closeTab()
|
||||
}.openHomeScreen { }.openThreeDotMenu {
|
||||
}
|
||||
|
||||
homeScreen { }.openThreeDotMenu {
|
||||
}.openHistory {
|
||||
longTapSelectItem(firstWebPage.url)
|
||||
openActionBarOverflowOrOptionsMenu(activityTestRule.activity)
|
||||
|
|
|
@ -8,6 +8,7 @@ import androidx.test.uiautomator.UiSelector
|
|||
import okhttp3.mockwebserver.MockWebServer
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Ignore
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.mozilla.fenix.helpers.AndroidAssetDispatcher
|
||||
|
@ -135,6 +136,7 @@ class MediaNotificationTest {
|
|||
}
|
||||
}
|
||||
|
||||
@Ignore("Flaky test, temp disabled: https://github.com/mozilla-mobile/fenix/issues/12645")
|
||||
@Test
|
||||
fun mediaSystemNotificationInPrivateModeTest() {
|
||||
val audioTestPage = TestAssetHelper.getAudioPageAsset(mockWebServer)
|
||||
|
@ -158,7 +160,7 @@ class MediaNotificationTest {
|
|||
verifyMediaIsPaused()
|
||||
}.openTabDrawer {
|
||||
closeTab()
|
||||
}.openHomeScreen { }
|
||||
}
|
||||
|
||||
mDevice.openNotification()
|
||||
|
||||
|
|
|
@ -58,8 +58,10 @@ class NavigationToolbarTest {
|
|||
mDevice.waitForIdle()
|
||||
}.openNavigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(nextWebPage.url) {
|
||||
mDevice.waitForIdle()
|
||||
verifyUrl(nextWebPage.url.toString())
|
||||
mDevice.pressBack()
|
||||
mDevice.waitForIdle()
|
||||
verifyUrl(defaultWebPage.url.toString())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -215,4 +215,39 @@ class SmokeTest {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun verifyETPToolbarShieldIconIsNotDisplayedIfETPIsOFFGloballyTest() {
|
||||
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
|
||||
|
||||
homeScreen {
|
||||
}.openThreeDotMenu {
|
||||
}.openSettings {
|
||||
}.openEnhancedTrackingProtectionSubMenu {
|
||||
clickEnhancedTrackingProtectionDefaults()
|
||||
verifyEnhancedTrackingProtectionOptionsGrayedOut()
|
||||
}.goBackToHomeScreen {
|
||||
navigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(defaultWebPage.url) {
|
||||
verifyEnhancedTrackingProtectionPanelNotVisible()
|
||||
}.openThreeDotMenu {
|
||||
}.clickAddOnsReportSiteIssue {
|
||||
verifyUrl("webcompat.com/issues/new")
|
||||
verifyTabCounter("2")
|
||||
}.openTabDrawer {
|
||||
}.openHomeScreen {
|
||||
}.openThreeDotMenu {
|
||||
}.openSettings {
|
||||
}.openEnhancedTrackingProtectionSubMenu {
|
||||
clickEnhancedTrackingProtectionDefaults()
|
||||
}.goBackToHomeScreen {
|
||||
}.openTabDrawer {
|
||||
}.openTab(defaultWebPage.title) {
|
||||
clickEnhancedTrackingProtectionPanel()
|
||||
verifyEnhancedTrackingProtectionSwitch()
|
||||
// Turning off TP Switch results in adding the WebPage to exception list
|
||||
clickEnhancedTrackingProtectionSwitchOffOn()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,7 +46,7 @@ class StrictEnhancedTrackingProtectionTest {
|
|||
start()
|
||||
}
|
||||
|
||||
InstrumentationRegistry.getInstrumentation().context.settings().setStrictETP()
|
||||
activityTestRule.activity.settings().setStrictETP()
|
||||
|
||||
// Reset on-boarding notification for each test
|
||||
TestHelper.setPreference(
|
||||
|
|
|
@ -9,6 +9,7 @@ import androidx.test.uiautomator.UiDevice
|
|||
import okhttp3.mockwebserver.MockWebServer
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.BeforeClass
|
||||
import org.junit.Ignore
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
|
@ -53,6 +54,16 @@ class TabbedBrowsingTest {
|
|||
}
|
||||
}
|
||||
|
||||
// changing the device preference for Touch and Hold delay, to avoid long-clicks instead of a single-click
|
||||
companion object {
|
||||
@BeforeClass
|
||||
@JvmStatic
|
||||
fun setDevicePreference() {
|
||||
val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
|
||||
mDevice.executeShellCommand("settings put secure long_press_timeout 3000")
|
||||
}
|
||||
}
|
||||
|
||||
@After
|
||||
fun tearDown() {
|
||||
mockWebServer.shutdown()
|
||||
|
@ -118,7 +129,6 @@ class TabbedBrowsingTest {
|
|||
verifySaveCollection()
|
||||
}.closeAllTabs {
|
||||
verifyNoTabsOpened()
|
||||
}.openHomeScreen {
|
||||
}
|
||||
|
||||
// Repeat for Private Tabs
|
||||
|
@ -134,8 +144,6 @@ class TabbedBrowsingTest {
|
|||
verifyCloseAllTabsButton()
|
||||
}.closeAllTabs {
|
||||
verifyNoTabsOpened()
|
||||
}.openHomeScreen {
|
||||
verifyPrivateSessionMessage()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ import androidx.test.espresso.matcher.ViewMatchers.isCompletelyDisplayed
|
|||
import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
|
||||
import androidx.test.espresso.matcher.ViewMatchers.withEffectiveVisibility
|
||||
import androidx.test.espresso.matcher.ViewMatchers.withId
|
||||
import androidx.test.espresso.matcher.ViewMatchers.withResourceName
|
||||
import androidx.test.espresso.matcher.ViewMatchers.withText
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import androidx.test.uiautomator.By
|
||||
|
@ -144,6 +145,8 @@ class BrowserRobot {
|
|||
|
||||
fun verifyEnhancedTrackingProtectionSwitch() = assertEnhancedTrackingProtectionSwitch()
|
||||
|
||||
fun clickEnhancedTrackingProtectionSwitchOffOn() = onView(withResourceName("switch_widget")).click()
|
||||
|
||||
fun verifyProtectionSettingsButton() = assertProtectionSettingsButton()
|
||||
|
||||
fun verifyEnhancedTrackingOptions() {
|
||||
|
@ -188,6 +191,8 @@ class BrowserRobot {
|
|||
|
||||
fun clickEnhancedTrackingProtectionPanel() = enhancedTrackingProtectionPanel().click()
|
||||
|
||||
fun verifyEnhancedTrackingProtectionPanelNotVisible() = assertEnhancedTrackingProtectionPanelNotVisible()
|
||||
|
||||
fun clickContextOpenLinkInNewTab() {
|
||||
val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
|
||||
mDevice.waitNotNull(
|
||||
|
@ -420,6 +425,11 @@ private fun assertNavURLBar() = navURLBar()
|
|||
|
||||
fun enhancedTrackingProtectionPanel() = onView(withId(R.id.mozac_browser_toolbar_tracking_protection_indicator))
|
||||
|
||||
private fun assertEnhancedTrackingProtectionPanelNotVisible() {
|
||||
enhancedTrackingProtectionPanel()
|
||||
.check(matches(withEffectiveVisibility(Visibility.GONE)))
|
||||
}
|
||||
|
||||
private fun assertEnhancedTrackingProtectionSwitch() {
|
||||
withText(R.id.trackingProtectionSwitch)
|
||||
.matches(withEffectiveVisibility(Visibility.VISIBLE))
|
||||
|
|
|
@ -63,6 +63,7 @@ class HomeScreenRobot {
|
|||
fun verifyHomeToolbar() = assertHomeToolbar()
|
||||
fun verifyHomeComponent() = assertHomeComponent()
|
||||
fun verifyDefaultSearchEngine(searchEngine: String) = verifySearchEngineIcon(searchEngine)
|
||||
fun verifyNoTabsOpened() = assertNoTabsOpened()
|
||||
|
||||
// First Run elements
|
||||
fun verifyWelcomeHeader() = assertWelcomeHeader()
|
||||
|
@ -529,6 +530,8 @@ private fun assertHomeComponent() =
|
|||
onView(ViewMatchers.withResourceName("sessionControlRecyclerView"))
|
||||
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
|
||||
|
||||
private fun assertNoTabsOpened() = onView(withId(R.id.counter_text)).check(matches(withText("0")))
|
||||
|
||||
private fun threeDotButton() = onView(allOf(withId(R.id.menuButton)))
|
||||
|
||||
private fun verifySearchEngineIcon(searchEngineIcon: Bitmap, searchEngineName: String) {
|
||||
|
|
|
@ -141,6 +141,7 @@ class SettingsRobot {
|
|||
}
|
||||
|
||||
fun openEnhancedTrackingProtectionSubMenu(interact: SettingsSubMenuEnhancedTrackingProtectionRobot.() -> Unit): SettingsSubMenuEnhancedTrackingProtectionRobot.Transition {
|
||||
scrollToElementByText("Enhanced Tracking Protection")
|
||||
fun enhancedTrackingProtectionButton() =
|
||||
onView(withText("Enhanced Tracking Protection"))
|
||||
enhancedTrackingProtectionButton().click()
|
||||
|
|
|
@ -7,6 +7,7 @@ package org.mozilla.fenix.ui.robots
|
|||
import androidx.preference.R
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.test.espresso.Espresso.onView
|
||||
import androidx.test.espresso.Espresso.pressBack
|
||||
import androidx.test.espresso.assertion.ViewAssertions.matches
|
||||
import androidx.test.espresso.contrib.RecyclerViewActions
|
||||
import androidx.test.espresso.matcher.ViewMatchers.hasDescendant
|
||||
|
@ -23,9 +24,11 @@ import androidx.test.espresso.matcher.ViewMatchers.withText
|
|||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import androidx.test.uiautomator.UiDevice
|
||||
import org.hamcrest.CoreMatchers.allOf
|
||||
import org.hamcrest.CoreMatchers.not
|
||||
import org.mozilla.fenix.helpers.assertIsChecked
|
||||
import org.mozilla.fenix.helpers.click
|
||||
import org.mozilla.fenix.helpers.isChecked
|
||||
import org.mozilla.fenix.helpers.isEnabled
|
||||
|
||||
/**
|
||||
* Implementation of Robot Pattern for the settings Enhanced Tracking Protection sub menu.
|
||||
|
@ -44,8 +47,12 @@ class SettingsSubMenuEnhancedTrackingProtectionRobot {
|
|||
|
||||
fun verifyEnhancedTrackingProtectionOptions() = assertEnhancedTrackingProtectionOptions()
|
||||
|
||||
fun verifyEnhancedTrackingProtectionOptionsGrayedOut() = assertEnhancedTrackingProtectionOptionsGrayedOut()
|
||||
|
||||
fun verifyEnhancedTrackingProtectionDefaults() = assertEnhancedTrackingProtectionDefaults()
|
||||
|
||||
fun clickEnhancedTrackingProtectionDefaults() = onView(withResourceName("switch_widget")).click()
|
||||
|
||||
fun verifyRadioButtonDefaults() = assertRadioButtonDefaults()
|
||||
|
||||
fun verifyEnhancedTrackingProtectionProtectionSubMenuItems() {
|
||||
|
@ -61,6 +68,16 @@ class SettingsSubMenuEnhancedTrackingProtectionRobot {
|
|||
class Transition {
|
||||
val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())!!
|
||||
|
||||
fun goBackToHomeScreen(interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition {
|
||||
// To settings
|
||||
goBackButton().click()
|
||||
// To HomeScreen
|
||||
pressBack()
|
||||
|
||||
HomeScreenRobot().interact()
|
||||
return HomeScreenRobot.Transition()
|
||||
}
|
||||
|
||||
fun goBack(interact: SettingsRobot.() -> Unit): SettingsRobot.Transition {
|
||||
goBackButton().click()
|
||||
|
||||
|
@ -141,6 +158,31 @@ private fun assertEnhancedTrackingProtectionOptions() {
|
|||
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
|
||||
}
|
||||
|
||||
private fun assertEnhancedTrackingProtectionOptionsGrayedOut() {
|
||||
onView(withText("Standard (default)"))
|
||||
.check(matches(not(isEnabled(true))))
|
||||
|
||||
val stdText = "Blocks fewer trackers. Pages will load normally."
|
||||
onView(withText(stdText))
|
||||
.check(matches(not(isEnabled(true))))
|
||||
|
||||
onView(withText("Strict"))
|
||||
.check(matches(not(isEnabled(true))))
|
||||
|
||||
val strictText =
|
||||
"Blocks more trackers, ads, and popups. Pages load faster, but some functionality might not work."
|
||||
onView(withText(strictText))
|
||||
.check(matches(not(isEnabled(true))))
|
||||
|
||||
onView(withText("Custom"))
|
||||
.check(matches(not(isEnabled(true))))
|
||||
|
||||
val customText =
|
||||
"Choose which trackers and scripts to block."
|
||||
onView(withText(customText))
|
||||
.check(matches(not(isEnabled(true))))
|
||||
}
|
||||
|
||||
private fun assertEnhancedTrackingProtectionDefaults() {
|
||||
onView(withResourceName("switch_widget")).check(
|
||||
matches(
|
||||
|
|
|
@ -253,12 +253,11 @@ class ThreeDotMenuMainRobot {
|
|||
return BrowserRobot.Transition()
|
||||
}
|
||||
|
||||
fun closeAllTabs(interact: TabDrawerRobot.() -> Unit): TabDrawerRobot.Transition {
|
||||
// mDevice.waitNotNull(Until.findObject(By.text("Close all tabs")), waitingTime)
|
||||
fun closeAllTabs(interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition {
|
||||
closeAllTabsButton().click()
|
||||
|
||||
TabDrawerRobot().interact()
|
||||
return TabDrawerRobot.Transition()
|
||||
HomeScreenRobot().interact()
|
||||
return HomeScreenRobot.Transition()
|
||||
}
|
||||
|
||||
fun openFindInPage(interact: FindInPageRobot.() -> Unit): FindInPageRobot.Transition {
|
||||
|
|
|
@ -10,7 +10,7 @@ import mozilla.components.concept.storage.LoginsStorage
|
|||
import mozilla.components.lib.crash.handler.CrashHandlerService
|
||||
import mozilla.components.service.sync.logins.GeckoLoginStorageDelegate
|
||||
import org.mozilla.fenix.Config
|
||||
import org.mozilla.fenix.utils.Settings
|
||||
import org.mozilla.fenix.ext.components
|
||||
import org.mozilla.geckoview.GeckoRuntime
|
||||
import org.mozilla.geckoview.GeckoRuntimeSettings
|
||||
|
||||
|
@ -48,9 +48,10 @@ object GeckoProvider {
|
|||
.debugLogging(Config.channel.isDebug)
|
||||
.build()
|
||||
|
||||
if (!Settings.getInstance(context).shouldUseAutoSize) {
|
||||
val settings = context.components.settings
|
||||
if (!settings.shouldUseAutoSize) {
|
||||
runtimeSettings.automaticFontSizeAdjustment = false
|
||||
val fontSize = Settings.getInstance(context).fontSizeFactor
|
||||
val fontSize = settings.fontSizeFactor
|
||||
runtimeSettings.fontSizeFactor = fontSize
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ import mozilla.components.concept.storage.LoginsStorage
|
|||
import mozilla.components.lib.crash.handler.CrashHandlerService
|
||||
import mozilla.components.service.sync.logins.GeckoLoginStorageDelegate
|
||||
import org.mozilla.fenix.Config
|
||||
import org.mozilla.fenix.utils.Settings
|
||||
import org.mozilla.fenix.ext.components
|
||||
import org.mozilla.geckoview.GeckoRuntime
|
||||
import org.mozilla.geckoview.GeckoRuntimeSettings
|
||||
|
||||
|
@ -48,9 +48,10 @@ object GeckoProvider {
|
|||
.aboutConfigEnabled(true)
|
||||
.build()
|
||||
|
||||
if (!Settings.getInstance(context).shouldUseAutoSize) {
|
||||
val settings = context.components.settings
|
||||
if (!settings.shouldUseAutoSize) {
|
||||
runtimeSettings.automaticFontSizeAdjustment = false
|
||||
val fontSize = Settings.getInstance(context).fontSizeFactor
|
||||
val fontSize = settings.fontSizeFactor
|
||||
runtimeSettings.fontSizeFactor = fontSize
|
||||
}
|
||||
|
||||
|
|
|
@ -7,13 +7,10 @@ package org.mozilla.fenix
|
|||
enum class ReleaseChannel {
|
||||
FenixDebug,
|
||||
|
||||
FenixNightly,
|
||||
FenixBeta,
|
||||
FenixProduction,
|
||||
|
||||
FennecProduction,
|
||||
FennecBeta,
|
||||
FennecNightly;
|
||||
FennecBeta;
|
||||
|
||||
val isReleased: Boolean
|
||||
get() = when (this) {
|
||||
|
@ -33,8 +30,6 @@ enum class ReleaseChannel {
|
|||
|
||||
val isReleaseOrBeta: Boolean
|
||||
get() = when (this) {
|
||||
FenixProduction -> true
|
||||
FenixBeta -> true
|
||||
FennecProduction -> true
|
||||
FennecBeta -> true
|
||||
else -> false
|
||||
|
@ -43,14 +38,11 @@ enum class ReleaseChannel {
|
|||
val isBeta: Boolean
|
||||
get() = when (this) {
|
||||
FennecBeta -> true
|
||||
FenixBeta -> true
|
||||
else -> false
|
||||
}
|
||||
|
||||
val isNightlyOrDebug: Boolean
|
||||
get() = when (this) {
|
||||
FenixNightly -> true
|
||||
FennecNightly -> true
|
||||
FenixDebug -> true
|
||||
FenixProduction -> true
|
||||
else -> false
|
||||
|
@ -66,12 +58,9 @@ enum class ReleaseChannel {
|
|||
object Config {
|
||||
val channel = when (BuildConfig.BUILD_TYPE) {
|
||||
"fenixProduction" -> ReleaseChannel.FenixProduction
|
||||
"fenixBeta" -> ReleaseChannel.FenixBeta
|
||||
"fenixNightly" -> ReleaseChannel.FenixNightly
|
||||
"debug" -> ReleaseChannel.FenixDebug
|
||||
"fennecProduction" -> ReleaseChannel.FennecProduction
|
||||
"fennecBeta" -> ReleaseChannel.FennecBeta
|
||||
"fennecNightly" -> ReleaseChannel.FennecNightly
|
||||
|
||||
// Builds for local performance analysis, recording benchmarks, automation, etc.
|
||||
// This should be treated like a released channel because we want to test
|
||||
|
@ -86,7 +75,6 @@ object Config {
|
|||
}
|
||||
|
||||
private val fennecChannels: List<ReleaseChannel> = listOf(
|
||||
ReleaseChannel.FennecNightly,
|
||||
ReleaseChannel.FennecBeta,
|
||||
ReleaseChannel.FennecProduction
|
||||
)
|
||||
|
|
|
@ -47,7 +47,6 @@ import org.mozilla.fenix.push.WebPushEngineIntegration
|
|||
import org.mozilla.fenix.session.PerformanceActivityLifecycleCallbacks
|
||||
import org.mozilla.fenix.session.VisibilityLifecycleCallback
|
||||
import org.mozilla.fenix.utils.BrowsersCache
|
||||
import org.mozilla.fenix.utils.Settings
|
||||
|
||||
/**
|
||||
*The main application class for Fenix. Records data to measure initialization performance.
|
||||
|
@ -355,8 +354,7 @@ open class FenixApplication : LocaleAwareApplication() {
|
|||
_, engineSession, url ->
|
||||
val shouldCreatePrivateSession =
|
||||
components.core.sessionManager.selectedSession?.private
|
||||
?: Settings.instance?.openLinksInAPrivateTab
|
||||
?: false
|
||||
?: components.settings.openLinksInAPrivateTab
|
||||
|
||||
val session = Session(url, shouldCreatePrivateSession)
|
||||
components.core.sessionManager.add(session, true, engineSession)
|
||||
|
|
|
@ -26,7 +26,6 @@ import androidx.navigation.fragment.NavHostFragment
|
|||
import androidx.navigation.ui.AppBarConfiguration
|
||||
import androidx.navigation.ui.NavigationUI
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import com.google.android.gms.tasks.Tasks.call
|
||||
import kotlinx.android.synthetic.main.activity_home.*
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
|
@ -65,7 +64,6 @@ import org.mozilla.fenix.browser.browsingmode.BrowsingModeManager
|
|||
import org.mozilla.fenix.browser.browsingmode.DefaultBrowsingModeManager
|
||||
import org.mozilla.fenix.components.metrics.BreadcrumbsRecorder
|
||||
import org.mozilla.fenix.components.metrics.Event
|
||||
import org.mozilla.fenix.trackingprotectionexceptions.TrackingProtectionExceptionsFragmentDirections
|
||||
import org.mozilla.fenix.ext.alreadyOnDestination
|
||||
import org.mozilla.fenix.ext.components
|
||||
import org.mozilla.fenix.ext.nav
|
||||
|
@ -87,8 +85,8 @@ import org.mozilla.fenix.session.NotificationSessionObserver
|
|||
import org.mozilla.fenix.settings.SettingsFragmentDirections
|
||||
import org.mozilla.fenix.settings.TrackingProtectionFragmentDirections
|
||||
import org.mozilla.fenix.settings.about.AboutFragmentDirections
|
||||
import org.mozilla.fenix.settings.logins.fragment.SavedLoginsAuthFragmentDirections
|
||||
import org.mozilla.fenix.settings.logins.fragment.LoginDetailFragmentDirections
|
||||
import org.mozilla.fenix.settings.logins.fragment.SavedLoginsAuthFragmentDirections
|
||||
import org.mozilla.fenix.settings.search.AddSearchEngineFragmentDirections
|
||||
import org.mozilla.fenix.settings.search.EditCustomSearchEngineFragmentDirections
|
||||
import org.mozilla.fenix.share.AddNewDeviceFragmentDirections
|
||||
|
@ -97,6 +95,7 @@ import org.mozilla.fenix.tabtray.FenixTabsAdapter
|
|||
import org.mozilla.fenix.tabtray.TabTrayDialogFragment
|
||||
import org.mozilla.fenix.theme.DefaultThemeManager
|
||||
import org.mozilla.fenix.theme.ThemeManager
|
||||
import org.mozilla.fenix.trackingprotectionexceptions.TrackingProtectionExceptionsFragmentDirections
|
||||
import org.mozilla.fenix.utils.BrowsersCache
|
||||
import org.mozilla.fenix.utils.RunWhenReadyQueue
|
||||
|
||||
|
@ -575,7 +574,7 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity {
|
|||
}
|
||||
|
||||
protected open fun createBrowsingModeManager(initialMode: BrowsingMode): BrowsingModeManager {
|
||||
return DefaultBrowsingModeManager(initialMode) { newMode ->
|
||||
return DefaultBrowsingModeManager(initialMode, components.settings) { newMode ->
|
||||
themeManager.currentTheme = newMode
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,7 +25,6 @@ import mozilla.components.feature.addons.ui.translatedName
|
|||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.ext.components
|
||||
import org.mozilla.fenix.ext.showToolbar
|
||||
import org.mozilla.fenix.utils.Settings
|
||||
|
||||
/**
|
||||
* An activity to show the details of a installed add-on.
|
||||
|
@ -191,8 +190,7 @@ class InstalledAddonDetailsFragment : Fragment() {
|
|||
val components = it.context.components
|
||||
val shouldCreatePrivateSession =
|
||||
components.core.store.state.selectedTab?.content?.private
|
||||
?: Settings.instance?.openLinksInAPrivateTab
|
||||
?: false
|
||||
?: components.settings.openLinksInAPrivateTab
|
||||
|
||||
if (shouldCreatePrivateSession) {
|
||||
components.useCases.tabsUseCases.addPrivateTab(settingUrl)
|
||||
|
|
|
@ -150,7 +150,8 @@ class BrowserFragment : BaseBrowserFragment(), UserInteractionHandler {
|
|||
|
||||
val toolbarSessionObserver = TrackingProtectionOverlay(
|
||||
context = context,
|
||||
settings = settings
|
||||
settings = settings,
|
||||
metrics = context.components.analytics.metrics
|
||||
) {
|
||||
browserToolbarView.view
|
||||
}
|
||||
|
|
|
@ -36,6 +36,7 @@ interface BrowsingModeManager {
|
|||
*/
|
||||
class DefaultBrowsingModeManager(
|
||||
private var _mode: BrowsingMode,
|
||||
private val settings: Settings,
|
||||
private val modeDidChange: (BrowsingMode) -> Unit
|
||||
) : BrowsingModeManager {
|
||||
|
||||
|
@ -44,6 +45,6 @@ class DefaultBrowsingModeManager(
|
|||
set(value) {
|
||||
_mode = value
|
||||
modeDidChange(value)
|
||||
Settings.instance?.lastKnownMode = value
|
||||
settings.lastKnownMode = value
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,8 +20,7 @@ import kotlinx.android.synthetic.main.tracking_protection_onboarding_popup.view.
|
|||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.components.SearchWidgetCreator
|
||||
import org.mozilla.fenix.components.metrics.Event
|
||||
import org.mozilla.fenix.ext.components
|
||||
import org.mozilla.fenix.ext.settings
|
||||
import org.mozilla.fenix.components.metrics.MetricController
|
||||
import org.mozilla.fenix.utils.Settings
|
||||
|
||||
/**
|
||||
|
@ -29,27 +28,29 @@ import org.mozilla.fenix.utils.Settings
|
|||
*/
|
||||
class SearchWidgetCFR(
|
||||
private val context: Context,
|
||||
private val settings: Settings,
|
||||
private val metrics: MetricController,
|
||||
private val getToolbar: () -> View
|
||||
) {
|
||||
|
||||
fun displayIfNecessary() {
|
||||
if (!context.settings().isInSearchWidgetExperiment ||
|
||||
!context.settings().shouldDisplaySearchWidgetCFR() ||
|
||||
isShown
|
||||
) { return }
|
||||
|
||||
isShown = true
|
||||
showSearchWidgetCFR()
|
||||
if (settings.isInSearchWidgetExperiment &&
|
||||
settings.shouldDisplaySearchWidgetCFR() &&
|
||||
!isShown
|
||||
) {
|
||||
isShown = true
|
||||
showSearchWidgetCFR()
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("MagicNumber", "InflateParams")
|
||||
@Suppress("InflateParams")
|
||||
private fun showSearchWidgetCFR() {
|
||||
context.settings().incrementSearchWidgetCFRDisplayed()
|
||||
settings.incrementSearchWidgetCFRDisplayed()
|
||||
|
||||
val searchWidgetCFRDialog = Dialog(context)
|
||||
val layout = LayoutInflater.from(context)
|
||||
.inflate(R.layout.search_widget_cfr, null)
|
||||
val isBottomToolbar = Settings.getInstance(context).shouldUseBottomToolbar
|
||||
val isBottomToolbar = settings.shouldUseBottomToolbar
|
||||
|
||||
layout.drop_down_triangle.isGone = isBottomToolbar
|
||||
layout.pop_up_triangle.isVisible = isBottomToolbar
|
||||
|
@ -63,16 +64,16 @@ class SearchWidgetCFR(
|
|||
}
|
||||
|
||||
layout.cfr_neg_button.setOnClickListener {
|
||||
context.components.analytics.metrics.track(Event.SearchWidgetCFRNotNowPressed)
|
||||
metrics.track(Event.SearchWidgetCFRNotNowPressed)
|
||||
searchWidgetCFRDialog.dismiss()
|
||||
context.settings().manuallyDismissSearchWidgetCFR()
|
||||
settings.manuallyDismissSearchWidgetCFR()
|
||||
}
|
||||
|
||||
layout.cfr_pos_button.setOnClickListener {
|
||||
context.components.analytics.metrics.track(Event.SearchWidgetCFRAddWidgetPressed)
|
||||
metrics.track(Event.SearchWidgetCFRAddWidgetPressed)
|
||||
SearchWidgetCreator.createSearchWidget(context)
|
||||
searchWidgetCFRDialog.dismiss()
|
||||
context.settings().manuallyDismissSearchWidgetCFR()
|
||||
settings.manuallyDismissSearchWidgetCFR()
|
||||
}
|
||||
|
||||
searchWidgetCFRDialog.apply {
|
||||
|
@ -90,16 +91,16 @@ class SearchWidgetCFR(
|
|||
|
||||
searchWidgetCFRDialog.setOnCancelListener {
|
||||
isShown = false
|
||||
context.components.analytics.metrics.track(Event.SearchWidgetCFRCanceled)
|
||||
metrics.track(Event.SearchWidgetCFRCanceled)
|
||||
}
|
||||
|
||||
searchWidgetCFRDialog.setOnDismissListener {
|
||||
isShown = false
|
||||
context.settings().incrementSearchWidgetCFRDismissed()
|
||||
settings.incrementSearchWidgetCFRDismissed()
|
||||
}
|
||||
|
||||
searchWidgetCFRDialog.show()
|
||||
context.components.analytics.metrics.track(Event.SearchWidgetCFRDisplayed)
|
||||
metrics.track(Event.SearchWidgetCFRDisplayed)
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
|
|
@ -10,6 +10,7 @@ import org.mozilla.fenix.home.Tab
|
|||
/**
|
||||
* Diff callback for comparing tab lists with selected state.
|
||||
*/
|
||||
@Suppress("LongParameterList")
|
||||
internal class TabDiffUtil(
|
||||
private val old: List<Tab>,
|
||||
private val new: List<Tab>,
|
||||
|
|
|
@ -103,11 +103,8 @@ private fun getSentryProjectUrl(): String? {
|
|||
val baseUrl = "https://sentry.prod.mozaws.net/operations"
|
||||
return when (Config.channel) {
|
||||
ReleaseChannel.FenixProduction -> "$baseUrl/fenix"
|
||||
ReleaseChannel.FenixBeta -> "$baseUrl/fenix-beta"
|
||||
ReleaseChannel.FenixNightly -> "$baseUrl/fenix-nightly"
|
||||
ReleaseChannel.FennecProduction -> "$baseUrl/fenix-fennec"
|
||||
ReleaseChannel.FennecBeta -> "$baseUrl/fenix-fennec-beta"
|
||||
ReleaseChannel.FennecNightly -> "$baseUrl/fenix-fennec-nightly"
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,6 +40,7 @@ import org.mozilla.fenix.ext.settings
|
|||
import org.mozilla.fenix.sync.SyncedTabsIntegration
|
||||
import org.mozilla.fenix.utils.Mockable
|
||||
import org.mozilla.fenix.utils.RunWhenReadyQueue
|
||||
import org.mozilla.fenix.utils.Settings
|
||||
|
||||
/**
|
||||
* Component group for background services. These are the components that need to be accessed from within a
|
||||
|
@ -103,7 +104,7 @@ class BackgroundServices(
|
|||
}
|
||||
|
||||
private val telemetryAccountObserver = TelemetryAccountObserver(
|
||||
context,
|
||||
context.settings(),
|
||||
context.components.analytics.metrics
|
||||
)
|
||||
|
||||
|
@ -178,8 +179,8 @@ class BackgroundServices(
|
|||
}
|
||||
|
||||
@VisibleForTesting(otherwise = PRIVATE)
|
||||
class TelemetryAccountObserver(
|
||||
private val context: Context,
|
||||
internal class TelemetryAccountObserver(
|
||||
private val settings: Settings,
|
||||
private val metricController: MetricController
|
||||
) : AccountObserver {
|
||||
override fun onAuthenticated(account: OAuthAccount, authType: AuthType) {
|
||||
|
@ -211,12 +212,12 @@ class TelemetryAccountObserver(
|
|||
metricController.track(Event.SyncAuthOtherExternal)
|
||||
}
|
||||
// Used by Leanplum as a context variable.
|
||||
context.settings().fxaSignedIn = true
|
||||
settings.fxaSignedIn = true
|
||||
}
|
||||
|
||||
override fun onLoggedOut() {
|
||||
metricController.track(Event.SyncAuthSignOut)
|
||||
// Used by Leanplum as a context variable.
|
||||
context.settings().fxaSignedIn = false
|
||||
settings.fxaSignedIn = false
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ import org.mozilla.fenix.BuildConfig
|
|||
import org.mozilla.fenix.HomeActivity
|
||||
import org.mozilla.fenix.utils.ClipboardHandler
|
||||
import org.mozilla.fenix.utils.Mockable
|
||||
import org.mozilla.fenix.utils.Settings
|
||||
import org.mozilla.fenix.wifi.WifiConnectionMonitor
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
|
@ -107,4 +108,6 @@ class Components(private val context: Context) {
|
|||
val performance by lazy { PerformanceComponent() }
|
||||
val push by lazy { Push(context, analytics.crashReporter) }
|
||||
val wifiConnectionMonitor by lazy { WifiConnectionMonitor(context.getSystemService()!!) }
|
||||
|
||||
val settings by lazy { Settings(context) }
|
||||
}
|
||||
|
|
|
@ -13,7 +13,6 @@ import com.adjust.sdk.AdjustConfig
|
|||
import com.adjust.sdk.LogLevel
|
||||
import org.mozilla.fenix.BuildConfig
|
||||
import org.mozilla.fenix.Config
|
||||
import org.mozilla.fenix.ReleaseChannel
|
||||
import org.mozilla.fenix.ext.settings
|
||||
|
||||
class AdjustMetricsService(private val application: Application) : MetricsService {
|
||||
|
@ -23,7 +22,7 @@ class AdjustMetricsService(private val application: Application) : MetricsServic
|
|||
if ((BuildConfig.ADJUST_TOKEN.isNullOrBlank())) {
|
||||
Log.i(LOGTAG, "No adjust token defined")
|
||||
|
||||
if (Config.channel.isReleased && Config.channel != ReleaseChannel.FennecNightly) {
|
||||
if (Config.channel.isReleased) {
|
||||
throw IllegalStateException("No adjust token defined for release build")
|
||||
}
|
||||
|
||||
|
|
|
@ -24,15 +24,14 @@ import mozilla.components.browser.state.selector.findTab
|
|||
import mozilla.components.browser.state.store.BrowserStore
|
||||
import mozilla.components.concept.storage.BookmarksStorage
|
||||
import mozilla.components.support.ktx.android.content.getColorFromAttr
|
||||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.FeatureFlags
|
||||
import org.mozilla.fenix.HomeActivity
|
||||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.browser.browsingmode.BrowsingMode
|
||||
import org.mozilla.fenix.ext.asActivity
|
||||
import org.mozilla.fenix.ext.components
|
||||
import org.mozilla.fenix.ext.settings
|
||||
import org.mozilla.fenix.theme.ThemeManager
|
||||
import org.mozilla.fenix.utils.Settings
|
||||
|
||||
/**
|
||||
* Builds the toolbar object used with the 3-dot menu in the browser fragment.
|
||||
|
@ -160,7 +159,7 @@ class DefaultToolbarMenu(
|
|||
// Predicates that are called once, during screen init
|
||||
val shouldShowSaveToCollection = (context.asActivity() as? HomeActivity)
|
||||
?.browsingModeManager?.mode == BrowsingMode.Normal
|
||||
val shouldDeleteDataOnQuit = Settings.getInstance(context)
|
||||
val shouldDeleteDataOnQuit = context.components.settings
|
||||
.shouldDeleteBrowsingDataOnQuit
|
||||
|
||||
val menuItems = listOfNotNull(
|
||||
|
|
|
@ -12,13 +12,10 @@ import android.view.ViewGroup
|
|||
import androidx.annotation.StringRes
|
||||
import mozilla.components.browser.search.SearchEngineManager
|
||||
import mozilla.components.support.locale.LocaleManager
|
||||
import org.mozilla.fenix.BuildConfig
|
||||
import org.mozilla.fenix.Config
|
||||
import org.mozilla.fenix.FenixApplication
|
||||
import org.mozilla.fenix.components.Components
|
||||
import org.mozilla.fenix.components.metrics.MetricController
|
||||
import org.mozilla.fenix.settings.advanced.getSelectedLocale
|
||||
import org.mozilla.fenix.utils.Settings
|
||||
import java.lang.String.format
|
||||
import java.util.Locale
|
||||
|
||||
|
@ -60,8 +57,7 @@ fun Context.getPreferenceKey(@StringRes resourceId: Int): String =
|
|||
fun Context.getRootView(): View? =
|
||||
asActivity()?.window?.decorView?.findViewById<View>(android.R.id.content) as? ViewGroup
|
||||
|
||||
fun Context.settings(isCrashReportEnabledInBuild: Boolean = BuildConfig.CRASH_REPORTING && Config.channel.isReleased) =
|
||||
Settings.getInstance(this, isCrashReportEnabledInBuild)
|
||||
fun Context.settings() = components.settings
|
||||
|
||||
/**
|
||||
* Used to catch IllegalArgumentException that is thrown when
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
/* 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.ext
|
||||
|
||||
import android.content.Context
|
||||
import android.text.Spannable
|
||||
import android.text.SpannableString
|
||||
import android.text.style.AbsoluteSizeSpan
|
||||
import android.text.style.ForegroundColorSpan
|
||||
import androidx.core.content.ContextCompat
|
||||
import mozilla.components.support.ktx.android.util.dpToPx
|
||||
|
||||
fun SpannableString.setTextSize(context: Context, textSize: Int) =
|
||||
this.setSpan(
|
||||
AbsoluteSizeSpan(textSize.dpToPx(context.resources.displayMetrics)),
|
||||
0,
|
||||
this.length,
|
||||
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
|
||||
)
|
||||
|
||||
fun SpannableString.setTextColor(context: Context, colorResId: Int) =
|
||||
this.setSpan(
|
||||
ForegroundColorSpan(
|
||||
ContextCompat.getColor(
|
||||
context,
|
||||
colorResId
|
||||
)
|
||||
),
|
||||
0,
|
||||
this.length,
|
||||
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
|
||||
)
|
|
@ -375,7 +375,13 @@ class HomeFragment : Fragment() {
|
|||
// the CFR in.
|
||||
view.toolbar_wrapper.doOnLayout {
|
||||
if (!browsingModeManager.mode.isPrivate) {
|
||||
SearchWidgetCFR(view.context) { view.toolbar_wrapper }.displayIfNecessary()
|
||||
SearchWidgetCFR(
|
||||
context = view.context,
|
||||
settings = view.context.settings(),
|
||||
metrics = view.context.components.analytics.metrics
|
||||
) {
|
||||
view.toolbar_wrapper
|
||||
}.displayIfNecessary()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -26,7 +26,6 @@ import org.mozilla.fenix.R
|
|||
import org.mozilla.fenix.ext.components
|
||||
import org.mozilla.fenix.ext.settings
|
||||
import org.mozilla.fenix.theme.ThemeManager
|
||||
import org.mozilla.fenix.utils.Settings
|
||||
import org.mozilla.fenix.whatsnew.WhatsNew
|
||||
|
||||
class HomeMenu(
|
||||
|
@ -153,40 +152,29 @@ class HomeMenu(
|
|||
null
|
||||
}
|
||||
|
||||
val settings = context.components.settings
|
||||
|
||||
val menuItems = listOfNotNull(
|
||||
if (settings.shouldDeleteBrowsingDataOnQuit) quitItem else null,
|
||||
settingsItem,
|
||||
BrowserMenuDivider(),
|
||||
if (FeatureFlags.syncedTabs) syncedTabsItem else null,
|
||||
bookmarksItem,
|
||||
historyItem,
|
||||
BrowserMenuDivider(),
|
||||
addons,
|
||||
BrowserMenuDivider(),
|
||||
whatsNewItem,
|
||||
helpItem,
|
||||
accountAuthItem
|
||||
).also { items ->
|
||||
items.getHighlight()?.let { onHighlightPresent(it) }
|
||||
}
|
||||
|
||||
if (shouldUseBottomToolbar) {
|
||||
listOfNotNull(
|
||||
accountAuthItem,
|
||||
helpItem,
|
||||
whatsNewItem,
|
||||
BrowserMenuDivider(),
|
||||
addons,
|
||||
BrowserMenuDivider(),
|
||||
historyItem,
|
||||
bookmarksItem,
|
||||
if (FeatureFlags.syncedTabs) syncedTabsItem else null,
|
||||
BrowserMenuDivider(),
|
||||
settingsItem,
|
||||
if (Settings.getInstance(context).shouldDeleteBrowsingDataOnQuit) quitItem else null
|
||||
).also { items ->
|
||||
items.getHighlight()?.let { onHighlightPresent(it) }
|
||||
}
|
||||
menuItems.reversed()
|
||||
} else {
|
||||
listOfNotNull(
|
||||
if (Settings.getInstance(context).shouldDeleteBrowsingDataOnQuit) quitItem else null,
|
||||
settingsItem,
|
||||
BrowserMenuDivider(),
|
||||
if (FeatureFlags.syncedTabs) syncedTabsItem else null,
|
||||
bookmarksItem,
|
||||
historyItem,
|
||||
BrowserMenuDivider(),
|
||||
addons,
|
||||
BrowserMenuDivider(),
|
||||
whatsNewItem,
|
||||
helpItem,
|
||||
accountAuthItem
|
||||
).also { items ->
|
||||
items.getHighlight()?.let { onHighlightPresent(it) }
|
||||
}
|
||||
menuItems
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -128,7 +128,7 @@ interface SessionControlController {
|
|||
fun handleCreateCollection()
|
||||
}
|
||||
|
||||
@SuppressWarnings("TooManyFunctions", "LargeClass")
|
||||
@SuppressWarnings("TooManyFunctions", "LargeClass", "LongParameterList")
|
||||
class DefaultSessionControlController(
|
||||
private val activity: HomeActivity,
|
||||
private val engine: Engine,
|
||||
|
|
|
@ -12,12 +12,13 @@ import org.mozilla.fenix.components.metrics.Event
|
|||
import org.mozilla.fenix.components.metrics.Event.OnboardingToolbarPosition.Position
|
||||
import org.mozilla.fenix.ext.asActivity
|
||||
import org.mozilla.fenix.ext.components
|
||||
import org.mozilla.fenix.ext.settings
|
||||
import org.mozilla.fenix.onboarding.OnboardingRadioButton
|
||||
import org.mozilla.fenix.utils.view.addToRadioGroup
|
||||
|
||||
class OnboardingToolbarPositionPickerViewHolder(view: View) : RecyclerView.ViewHolder(view) {
|
||||
|
||||
private val metrics = view.context.components.analytics.metrics
|
||||
|
||||
init {
|
||||
val radioTopToolbar = view.toolbar_top_radio_button
|
||||
val radioBottomToolbar = view.toolbar_bottom_radio_button
|
||||
|
@ -27,7 +28,8 @@ class OnboardingToolbarPositionPickerViewHolder(view: View) : RecyclerView.ViewH
|
|||
radioTopToolbar.addIllustration(view.toolbar_top_image)
|
||||
radioBottomToolbar.addIllustration(view.toolbar_bottom_image)
|
||||
|
||||
radio = if (view.context.settings().shouldUseBottomToolbar) {
|
||||
val settings = view.context.components.settings
|
||||
radio = if (settings.shouldUseBottomToolbar) {
|
||||
radioBottomToolbar
|
||||
} else {
|
||||
radioTopToolbar
|
||||
|
@ -35,28 +37,24 @@ class OnboardingToolbarPositionPickerViewHolder(view: View) : RecyclerView.ViewH
|
|||
radio.updateRadioValue(true)
|
||||
|
||||
radioBottomToolbar.onClickListener {
|
||||
itemView.context.components.analytics.metrics
|
||||
.track(Event.OnboardingToolbarPosition(Position.BOTTOM))
|
||||
metrics.track(Event.OnboardingToolbarPosition(Position.BOTTOM))
|
||||
|
||||
itemView.context.asActivity()?.recreate()
|
||||
}
|
||||
|
||||
view.toolbar_bottom_image.setOnClickListener {
|
||||
itemView.context.components.analytics.metrics
|
||||
.track(Event.OnboardingToolbarPosition(Position.BOTTOM))
|
||||
metrics.track(Event.OnboardingToolbarPosition(Position.BOTTOM))
|
||||
|
||||
radioBottomToolbar.performClick()
|
||||
}
|
||||
|
||||
radioTopToolbar.onClickListener {
|
||||
itemView.context.components.analytics.metrics
|
||||
.track(Event.OnboardingToolbarPosition(Position.TOP))
|
||||
metrics.track(Event.OnboardingToolbarPosition(Position.TOP))
|
||||
itemView.context.asActivity()?.recreate()
|
||||
}
|
||||
|
||||
view.toolbar_top_image.setOnClickListener {
|
||||
itemView.context.components.analytics.metrics
|
||||
.track(Event.OnboardingToolbarPosition(Position.TOP))
|
||||
metrics.track(Event.OnboardingToolbarPosition(Position.TOP))
|
||||
radioTopToolbar.performClick()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,17 +37,17 @@ class OnboardingTrackingProtectionViewHolder(view: View) : RecyclerView.ViewHold
|
|||
isChecked = view.context.settings().shouldUseTrackingProtection
|
||||
setOnCheckedChangeListener { _, isChecked ->
|
||||
updateTrackingProtectionSetting(isChecked)
|
||||
updateRadioGroupState(view, isChecked)
|
||||
updateRadioGroupState(isChecked)
|
||||
}
|
||||
}
|
||||
|
||||
setupRadioGroup(view, trackingProtectionToggle.isChecked)
|
||||
updateRadioGroupState(view, trackingProtectionToggle.isChecked)
|
||||
setupRadioGroup(trackingProtectionToggle.isChecked)
|
||||
updateRadioGroupState(trackingProtectionToggle.isChecked)
|
||||
}
|
||||
|
||||
private fun setupRadioGroup(view: View, isChecked: Boolean) {
|
||||
private fun setupRadioGroup(isChecked: Boolean) {
|
||||
|
||||
updateRadioGroupState(view, isChecked)
|
||||
updateRadioGroupState(isChecked)
|
||||
|
||||
addToRadioGroup(standardTrackingProtection, strictTrackingProtection)
|
||||
|
||||
|
@ -58,56 +58,20 @@ class OnboardingTrackingProtectionViewHolder(view: View) : RecyclerView.ViewHold
|
|||
|
||||
standardTrackingProtection.onClickListener {
|
||||
updateTrackingProtectionPolicy()
|
||||
view.context.components.analytics.metrics
|
||||
itemView.context.components.analytics.metrics
|
||||
.track(Event.OnboardingTrackingProtection(Setting.STANDARD))
|
||||
}
|
||||
|
||||
view.clickable_region_standard.apply {
|
||||
setOnClickListener {
|
||||
standardTrackingProtection.performClick()
|
||||
view.context.components.analytics.metrics
|
||||
.track(Event.OnboardingTrackingProtection(Setting.STANDARD))
|
||||
}
|
||||
val standardTitle = view.context.getString(
|
||||
R.string.onboarding_tracking_protection_standard_button_2
|
||||
)
|
||||
val standardSummary = view.context.getString(
|
||||
R.string.onboarding_tracking_protection_standard_button_description_2
|
||||
)
|
||||
contentDescription = "$standardTitle. $standardSummary"
|
||||
}
|
||||
|
||||
strictTrackingProtection.onClickListener {
|
||||
updateTrackingProtectionPolicy()
|
||||
view.context.components.analytics.metrics
|
||||
itemView.context.components.analytics.metrics
|
||||
.track(Event.OnboardingTrackingProtection(Setting.STRICT))
|
||||
}
|
||||
|
||||
view.clickable_region_strict.apply {
|
||||
setOnClickListener {
|
||||
strictTrackingProtection.performClick()
|
||||
view.context.components.analytics.metrics
|
||||
.track(Event.OnboardingTrackingProtection(Setting.STRICT))
|
||||
}
|
||||
val strictTitle =
|
||||
view.context.getString(R.string.onboarding_tracking_protection_strict_option)
|
||||
val strictSummary =
|
||||
view.context.getString(R.string.onboarding_tracking_protection_strict_button_description_2)
|
||||
contentDescription = "$strictTitle. $strictSummary"
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateRadioGroupState(view: View, isChecked: Boolean) {
|
||||
private fun updateRadioGroupState(isChecked: Boolean) {
|
||||
standardTrackingProtection.isEnabled = isChecked
|
||||
strictTrackingProtection.isEnabled = isChecked
|
||||
|
||||
view.protection_standard_description.isEnabled = isChecked
|
||||
view.protection_strict_description.isEnabled = isChecked
|
||||
view.clickable_region_standard.isClickable = isChecked
|
||||
|
||||
view.protection_standard_title.isEnabled = isChecked
|
||||
view.protection_strict_title.isEnabled = isChecked
|
||||
view.clickable_region_strict.isClickable = isChecked
|
||||
}
|
||||
|
||||
private fun updateTrackingProtectionSetting(enabled: Boolean) {
|
||||
|
|
|
@ -47,7 +47,7 @@ interface BookmarkController {
|
|||
fun handleBackPressed()
|
||||
}
|
||||
|
||||
@SuppressWarnings("TooManyFunctions")
|
||||
@SuppressWarnings("TooManyFunctions", "LongParameterList")
|
||||
class DefaultBookmarkController(
|
||||
private val activity: HomeActivity,
|
||||
private val navController: NavController,
|
||||
|
|
|
@ -51,6 +51,7 @@ import org.mozilla.fenix.ext.nav
|
|||
import org.mozilla.fenix.ext.requireComponents
|
||||
import org.mozilla.fenix.ext.toShortUrl
|
||||
import org.mozilla.fenix.library.LibraryPageFragment
|
||||
import org.mozilla.fenix.tabtray.TabTrayDialogFragment
|
||||
import org.mozilla.fenix.utils.allowUndo
|
||||
|
||||
/**
|
||||
|
@ -207,14 +208,14 @@ class BookmarkFragment : LibraryPageFragment<BookmarkNode>(), UserInteractionHan
|
|||
R.id.open_bookmarks_in_new_tabs_multi_select -> {
|
||||
openItemsInNewTab { node -> node.url }
|
||||
|
||||
navigate(BookmarkFragmentDirections.actionGlobalTabTrayDialogFragment())
|
||||
showTabTray()
|
||||
metrics?.track(Event.OpenedBookmarksInNewTabs)
|
||||
true
|
||||
}
|
||||
R.id.open_bookmarks_in_private_tabs_multi_select -> {
|
||||
openItemsInNewTab(private = true) { node -> node.url }
|
||||
|
||||
navigate(BookmarkFragmentDirections.actionGlobalTabTrayDialogFragment())
|
||||
showTabTray()
|
||||
metrics?.track(Event.OpenedBookmarksInPrivateTabs)
|
||||
true
|
||||
}
|
||||
|
@ -237,6 +238,11 @@ class BookmarkFragment : LibraryPageFragment<BookmarkNode>(), UserInteractionHan
|
|||
}
|
||||
}
|
||||
|
||||
private fun showTabTray() {
|
||||
invokePendingDeletion()
|
||||
TabTrayDialogFragment.show(parentFragmentManager)
|
||||
}
|
||||
|
||||
private fun navigate(directions: NavDirections) {
|
||||
invokePendingDeletion()
|
||||
findNavController().nav(
|
||||
|
|
|
@ -44,6 +44,7 @@ import org.mozilla.fenix.ext.requireComponents
|
|||
import org.mozilla.fenix.ext.showToolbar
|
||||
import org.mozilla.fenix.ext.toShortUrl
|
||||
import org.mozilla.fenix.library.LibraryPageFragment
|
||||
import org.mozilla.fenix.tabtray.TabTrayDialogFragment
|
||||
import org.mozilla.fenix.utils.allowUndo
|
||||
|
||||
@SuppressWarnings("TooManyFunctions", "LargeClass")
|
||||
|
@ -184,9 +185,7 @@ class HistoryFragment : LibraryPageFragment<HistoryItem>(), UserInteractionHandl
|
|||
selectedItem.url
|
||||
}
|
||||
|
||||
navigate(
|
||||
HistoryFragmentDirections.actionGlobalTabTrayDialogFragment()
|
||||
)
|
||||
showTabTray()
|
||||
true
|
||||
}
|
||||
R.id.open_history_in_private_tabs_multi_select -> {
|
||||
|
@ -199,14 +198,18 @@ class HistoryFragment : LibraryPageFragment<HistoryItem>(), UserInteractionHandl
|
|||
browsingModeManager.mode = BrowsingMode.Private
|
||||
supportActionBar?.hide()
|
||||
}
|
||||
navigate(
|
||||
HistoryFragmentDirections.actionGlobalTabTrayDialogFragment()
|
||||
)
|
||||
|
||||
showTabTray()
|
||||
true
|
||||
}
|
||||
else -> super.onOptionsItemSelected(item)
|
||||
}
|
||||
|
||||
private fun showTabTray() {
|
||||
invokePendingDeletion()
|
||||
TabTrayDialogFragment.show(parentFragmentManager)
|
||||
}
|
||||
|
||||
private fun getMultiSelectSnackBarMessage(historyItems: Set<HistoryItem>): String {
|
||||
return if (historyItems.size > 1) {
|
||||
getString(R.string.history_delete_multiple_items_snackbar)
|
||||
|
|
|
@ -5,12 +5,16 @@
|
|||
package org.mozilla.fenix.onboarding
|
||||
|
||||
import android.content.Context
|
||||
import android.text.SpannableString
|
||||
import android.text.SpannableStringBuilder
|
||||
import android.util.AttributeSet
|
||||
import android.widget.ImageView
|
||||
import androidx.appcompat.widget.AppCompatRadioButton
|
||||
import androidx.core.content.edit
|
||||
import androidx.core.content.withStyledAttributes
|
||||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.ext.setTextColor
|
||||
import org.mozilla.fenix.ext.setTextSize
|
||||
import org.mozilla.fenix.ext.settings
|
||||
import org.mozilla.fenix.utils.view.GroupableRadioButton
|
||||
import org.mozilla.fenix.utils.view.uncheckAll
|
||||
|
@ -23,6 +27,8 @@ class OnboardingRadioButton(
|
|||
private var illustration: ImageView? = null
|
||||
private var clickListener: (() -> Unit)? = null
|
||||
var key: Int = 0
|
||||
var title: Int = 0
|
||||
var description: Int = 0
|
||||
|
||||
init {
|
||||
context.withStyledAttributes(
|
||||
|
@ -31,6 +37,9 @@ class OnboardingRadioButton(
|
|||
0, 0
|
||||
) {
|
||||
key = getResourceId(R.styleable.OnboardingRadioButton_onboardingKey, 0)
|
||||
title = getResourceId(R.styleable.OnboardingRadioButton_onboardingKeyTitle, 0)
|
||||
description =
|
||||
getResourceId(R.styleable.OnboardingRadioButton_onboardingKeyDescription, 0)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -52,6 +61,28 @@ class OnboardingRadioButton(
|
|||
toggleRadioGroups()
|
||||
clickListener?.invoke()
|
||||
}
|
||||
if (title != 0) {
|
||||
setRadioButtonText(context)
|
||||
}
|
||||
}
|
||||
|
||||
private fun setRadioButtonText(context: Context) {
|
||||
val builder = SpannableStringBuilder()
|
||||
|
||||
val spannableTitle = SpannableString(resources.getString(title))
|
||||
spannableTitle.setTextSize(context, TITLE_TEXT_SIZE)
|
||||
spannableTitle.setTextColor(context, R.color.primary_state_list_text_color)
|
||||
|
||||
builder.append(spannableTitle)
|
||||
|
||||
if (description != 0) {
|
||||
val spannableDescription = SpannableString(resources.getString(description))
|
||||
spannableDescription.setTextSize(context, DESCRIPTION_TEXT_SIZE)
|
||||
spannableDescription.setTextColor(context, R.color.secondary_state_list_text_color)
|
||||
builder.append("\n")
|
||||
builder.append(spannableDescription)
|
||||
}
|
||||
this.text = builder
|
||||
}
|
||||
|
||||
override fun updateRadioValue(isChecked: Boolean) {
|
||||
|
@ -69,4 +100,9 @@ class OnboardingRadioButton(
|
|||
radioGroups.uncheckAll()
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val TITLE_TEXT_SIZE = 16
|
||||
private const val DESCRIPTION_TEXT_SIZE = 14
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,8 +8,8 @@ import android.content.Context
|
|||
import android.content.Intent
|
||||
import android.content.IntentFilter
|
||||
import android.os.BatteryManager
|
||||
import org.mozilla.fenix.ext.components
|
||||
import org.mozilla.fenix.onboarding.FenixOnboarding
|
||||
import org.mozilla.fenix.utils.Settings
|
||||
import android.provider.Settings as AndroidSettings
|
||||
|
||||
/**
|
||||
|
@ -67,13 +67,13 @@ object Performance {
|
|||
* Disables the tracking protection popup. However, TP is still on.
|
||||
*/
|
||||
private fun disableTrackingProtectionPopups(context: Context) {
|
||||
Settings.getInstance(context).isOverrideTPPopupsForPerformanceTest = true
|
||||
context.components.settings.isOverrideTPPopupsForPerformanceTest = true
|
||||
}
|
||||
|
||||
/**
|
||||
* Disables the first time PWA popup.
|
||||
*/
|
||||
private fun disableFirstTimePWAPopup(context: Context) {
|
||||
Settings.getInstance(context).userKnowsAboutPwas = true
|
||||
context.components.settings.userKnowsAboutPwas = true
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ package org.mozilla.fenix.push
|
|||
|
||||
import android.util.Base64
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.MainScope
|
||||
import kotlinx.coroutines.launch
|
||||
import mozilla.components.concept.engine.Engine
|
||||
import mozilla.components.concept.engine.webpush.WebPushDelegate
|
||||
|
@ -22,7 +22,8 @@ import mozilla.components.support.base.log.logger.Logger
|
|||
*/
|
||||
class WebPushEngineIntegration(
|
||||
private val engine: Engine,
|
||||
private val pushFeature: AutoPushFeature
|
||||
private val pushFeature: AutoPushFeature,
|
||||
private val coroutineScope: CoroutineScope = MainScope()
|
||||
) : AutoPushFeature.Observer {
|
||||
|
||||
private var handler: WebPushHandler? = null
|
||||
|
@ -39,13 +40,13 @@ class WebPushEngineIntegration(
|
|||
}
|
||||
|
||||
override fun onMessageReceived(scope: PushScope, message: ByteArray?) {
|
||||
CoroutineScope(Dispatchers.Main).launch {
|
||||
coroutineScope.launch {
|
||||
handler?.onPushMessage(scope, message)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onSubscriptionChanged(scope: PushScope) {
|
||||
CoroutineScope(Dispatchers.Main).launch {
|
||||
coroutineScope.launch {
|
||||
handler?.onSubscriptionChanged(scope)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
/* 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.search.awesomebar
|
||||
|
||||
import mozilla.components.browser.search.SearchEngine
|
||||
import mozilla.components.browser.session.Session
|
||||
|
||||
/**
|
||||
* Interface for the AwesomeBarView Interactor. This interface is implemented by objects that want
|
||||
* to respond to user interaction on the AwesomebarView
|
||||
*/
|
||||
interface AwesomeBarInteractor {
|
||||
|
||||
/**
|
||||
* Called whenever a suggestion containing a URL is tapped
|
||||
* @param url the url the suggestion was providing
|
||||
*/
|
||||
fun onUrlTapped(url: String)
|
||||
|
||||
/**
|
||||
* Called whenever a search engine suggestion is tapped
|
||||
* @param searchTerms the query contained by the search suggestion
|
||||
*/
|
||||
fun onSearchTermsTapped(searchTerms: String)
|
||||
|
||||
/**
|
||||
* Called whenever a search engine shortcut is tapped
|
||||
* @param searchEngine the searchEngine that was selected
|
||||
*/
|
||||
fun onSearchShortcutEngineSelected(searchEngine: SearchEngine)
|
||||
|
||||
/**
|
||||
* Called whenever the "Search Engine Settings" item is tapped
|
||||
*/
|
||||
fun onClickSearchEngineSettings()
|
||||
|
||||
/**
|
||||
* Called whenever an existing session is selected from the sessionSuggestionProvider
|
||||
*/
|
||||
fun onExistingSessionSelected(session: Session)
|
||||
|
||||
/**
|
||||
* Called whenever an existing session is selected from the sessionSuggestionProvider
|
||||
*/
|
||||
fun onExistingSessionSelected(tabId: String)
|
||||
|
||||
/**
|
||||
* Called whenever the Shortcuts button is clicked
|
||||
*/
|
||||
fun onSearchShortcutsButtonClicked()
|
||||
}
|
|
@ -16,6 +16,7 @@ import mozilla.components.concept.awesomebar.AwesomeBar
|
|||
import mozilla.components.concept.engine.EngineSession
|
||||
import mozilla.components.feature.awesomebar.provider.BookmarksStorageSuggestionProvider
|
||||
import mozilla.components.feature.awesomebar.provider.HistoryStorageSuggestionProvider
|
||||
import mozilla.components.feature.awesomebar.provider.SearchActionProvider
|
||||
import mozilla.components.feature.awesomebar.provider.SearchSuggestionProvider
|
||||
import mozilla.components.feature.awesomebar.provider.SessionSuggestionProvider
|
||||
import mozilla.components.feature.search.SearchUseCases
|
||||
|
@ -29,51 +30,6 @@ import org.mozilla.fenix.ext.components
|
|||
import org.mozilla.fenix.search.SearchEngineSource
|
||||
import org.mozilla.fenix.search.SearchFragmentState
|
||||
|
||||
/**
|
||||
* Interface for the AwesomeBarView Interactor. This interface is implemented by objects that want
|
||||
* to respond to user interaction on the AwesomebarView
|
||||
*/
|
||||
interface AwesomeBarInteractor {
|
||||
|
||||
/**
|
||||
* Called whenever a suggestion containing a URL is tapped
|
||||
* @param url the url the suggestion was providing
|
||||
*/
|
||||
fun onUrlTapped(url: String)
|
||||
|
||||
/**
|
||||
* Called whenever a search engine suggestion is tapped
|
||||
* @param searchTerms the query contained by the search suggestion
|
||||
*/
|
||||
fun onSearchTermsTapped(searchTerms: String)
|
||||
|
||||
/**
|
||||
* Called whenever a search engine shortcut is tapped
|
||||
* @param searchEngine the searchEngine that was selected
|
||||
*/
|
||||
fun onSearchShortcutEngineSelected(searchEngine: SearchEngine)
|
||||
|
||||
/**
|
||||
* Called whenever the "Search Engine Settings" item is tapped
|
||||
*/
|
||||
fun onClickSearchEngineSettings()
|
||||
|
||||
/**
|
||||
* Called whenever an existing session is selected from the sessionSuggestionProvider
|
||||
*/
|
||||
fun onExistingSessionSelected(session: Session)
|
||||
|
||||
/**
|
||||
* Called whenever an existing session is selected from the sessionSuggestionProvider
|
||||
*/
|
||||
fun onExistingSessionSelected(tabId: String)
|
||||
|
||||
/**
|
||||
* Called whenever the Shortcuts button is clicked
|
||||
*/
|
||||
fun onSearchShortcutsButtonClicked()
|
||||
}
|
||||
|
||||
/**
|
||||
* View that contains and configures the BrowserAwesomeBar
|
||||
*/
|
||||
|
@ -88,7 +44,8 @@ class AwesomeBarView(
|
|||
private val shortcutsEnginePickerProvider: ShortcutsSuggestionProvider
|
||||
private val bookmarksStorageSuggestionProvider: BookmarksStorageSuggestionProvider
|
||||
private val defaultSearchSuggestionProvider: SearchSuggestionProvider
|
||||
private val searchSuggestionProviderMap: MutableMap<SearchEngine, SearchSuggestionProvider>
|
||||
private val defaultSearchActionProvider: SearchActionProvider
|
||||
private val searchSuggestionProviderMap: MutableMap<SearchEngine, List<AwesomeBar.SuggestionProvider>>
|
||||
private var providersInUse = mutableSetOf<AwesomeBar.SuggestionProvider>()
|
||||
|
||||
private val loadUrlUseCase = object : SessionUseCases.LoadUrlUseCase {
|
||||
|
@ -141,7 +98,8 @@ class AwesomeBarView(
|
|||
val draw = getDrawable(context, R.drawable.ic_link)!!
|
||||
draw.colorFilter = createBlendModeColorFilterCompat(primaryTextColor, SRC_IN)
|
||||
|
||||
val engineForSpeculativeConnects = if (!isBrowsingModePrivate()) components.core.engine else null
|
||||
val engineForSpeculativeConnects =
|
||||
if (!isBrowsingModePrivate()) components.core.engine else null
|
||||
sessionProvider =
|
||||
SessionSuggestionProvider(
|
||||
context.resources,
|
||||
|
@ -167,8 +125,9 @@ class AwesomeBarView(
|
|||
engineForSpeculativeConnects
|
||||
)
|
||||
|
||||
val searchDrawable = getDrawable(context, R.drawable.ic_search)!!
|
||||
searchDrawable.colorFilter = createBlendModeColorFilterCompat(primaryTextColor, SRC_IN)
|
||||
val searchBitmap = getDrawable(context, R.drawable.ic_search)!!.apply {
|
||||
colorFilter = createBlendModeColorFilterCompat(primaryTextColor, SRC_IN)
|
||||
}.toBitmap()
|
||||
|
||||
defaultSearchSuggestionProvider =
|
||||
SearchSuggestionProvider(
|
||||
|
@ -178,9 +137,20 @@ class AwesomeBarView(
|
|||
fetchClient = components.core.client,
|
||||
mode = SearchSuggestionProvider.Mode.MULTIPLE_SUGGESTIONS,
|
||||
limit = 3,
|
||||
icon = searchDrawable.toBitmap(),
|
||||
icon = searchBitmap,
|
||||
showDescription = false,
|
||||
engine = engineForSpeculativeConnects
|
||||
engine = engineForSpeculativeConnects,
|
||||
filterExactMatch = true
|
||||
)
|
||||
|
||||
defaultSearchActionProvider =
|
||||
SearchActionProvider(
|
||||
searchEngineGetter = suspend {
|
||||
components.search.searchEngineManager.getDefaultSearchEngineAsync(context)
|
||||
},
|
||||
searchUseCase = searchUseCase,
|
||||
icon = searchBitmap,
|
||||
showDescription = false
|
||||
)
|
||||
|
||||
shortcutsEnginePickerProvider =
|
||||
|
@ -248,9 +218,7 @@ class AwesomeBarView(
|
|||
}
|
||||
|
||||
if (state.showSearchSuggestions) {
|
||||
getSelectedSearchSuggestionProvider(state)?.let {
|
||||
providersToAdd.add(it)
|
||||
}
|
||||
providersToAdd.addAll(getSelectedSearchSuggestionProvider(state))
|
||||
}
|
||||
|
||||
if (!isBrowsingModePrivate()) {
|
||||
|
@ -274,9 +242,7 @@ class AwesomeBarView(
|
|||
}
|
||||
|
||||
if (!state.showSearchSuggestions) {
|
||||
getSelectedSearchSuggestionProvider(state)?.let {
|
||||
providersToRemove.add(it)
|
||||
}
|
||||
providersToRemove.addAll(getSelectedSearchSuggestionProvider(state))
|
||||
}
|
||||
|
||||
if (isBrowsingModePrivate()) {
|
||||
|
@ -291,9 +257,12 @@ class AwesomeBarView(
|
|||
?: false
|
||||
}
|
||||
|
||||
private fun getSelectedSearchSuggestionProvider(state: SearchFragmentState): SearchSuggestionProvider? {
|
||||
private fun getSelectedSearchSuggestionProvider(state: SearchFragmentState): List<AwesomeBar.SuggestionProvider> {
|
||||
return when (state.searchEngineSource) {
|
||||
is SearchEngineSource.Default -> defaultSearchSuggestionProvider
|
||||
is SearchEngineSource.Default -> listOf(
|
||||
defaultSearchActionProvider,
|
||||
defaultSearchSuggestionProvider
|
||||
)
|
||||
is SearchEngineSource.Shortcut -> getSuggestionProviderForEngine(
|
||||
state.searchEngineSource.searchEngine
|
||||
)
|
||||
|
@ -307,26 +276,38 @@ class AwesomeBarView(
|
|||
view.addProviders(shortcutsEnginePickerProvider)
|
||||
}
|
||||
|
||||
private fun getSuggestionProviderForEngine(engine: SearchEngine): SearchSuggestionProvider? {
|
||||
private fun getSuggestionProviderForEngine(engine: SearchEngine): List<AwesomeBar.SuggestionProvider> {
|
||||
return searchSuggestionProviderMap.getOrPut(engine) {
|
||||
val context = container.context
|
||||
val components = context.components
|
||||
val primaryTextColor = context.getColorFromAttr(R.attr.primaryText)
|
||||
|
||||
val draw = getDrawable(context, R.drawable.ic_search)
|
||||
draw?.colorFilter = createBlendModeColorFilterCompat(primaryTextColor, SRC_IN)
|
||||
val searchBitmap = getDrawable(context, R.drawable.ic_search)?.apply {
|
||||
colorFilter = createBlendModeColorFilterCompat(primaryTextColor, SRC_IN)
|
||||
}?.toBitmap()
|
||||
|
||||
val engineForSpeculativeConnects = if (!isBrowsingModePrivate()) components.core.engine else null
|
||||
|
||||
SearchSuggestionProvider(
|
||||
val engineForSpeculativeConnects =
|
||||
if (!isBrowsingModePrivate()) components.core.engine else null
|
||||
val searchEngine =
|
||||
components.search.provider.installedSearchEngines(context).list.find { it.name == engine.name }
|
||||
?: components.search.provider.getDefaultEngine(context),
|
||||
shortcutSearchUseCase,
|
||||
components.core.client,
|
||||
limit = 3,
|
||||
mode = SearchSuggestionProvider.Mode.MULTIPLE_SUGGESTIONS,
|
||||
icon = draw?.toBitmap(),
|
||||
engine = engineForSpeculativeConnects
|
||||
?: components.search.provider.getDefaultEngine(context)
|
||||
|
||||
listOf(
|
||||
SearchActionProvider(
|
||||
searchEngineGetter = suspend { searchEngine },
|
||||
searchUseCase = shortcutSearchUseCase,
|
||||
icon = searchBitmap
|
||||
),
|
||||
SearchSuggestionProvider(
|
||||
searchEngine,
|
||||
shortcutSearchUseCase,
|
||||
components.core.client,
|
||||
limit = 3,
|
||||
mode = SearchSuggestionProvider.Mode.MULTIPLE_SUGGESTIONS,
|
||||
icon = searchBitmap,
|
||||
engine = engineForSpeculativeConnects,
|
||||
filterExactMatch = true
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ package org.mozilla.fenix.search.toolbar
|
|||
import android.content.Context
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.drawable.BitmapDrawable
|
||||
import androidx.annotation.VisibleForTesting
|
||||
import androidx.appcompat.content.res.AppCompatResources
|
||||
import androidx.core.content.ContextCompat
|
||||
import mozilla.components.browser.domains.autocomplete.ShippedDomainsProvider
|
||||
|
@ -56,7 +57,8 @@ class ToolbarView(
|
|||
engine: Engine
|
||||
) {
|
||||
|
||||
private var isInitialized = false
|
||||
@VisibleForTesting
|
||||
internal var isInitialized = false
|
||||
|
||||
init {
|
||||
view.apply {
|
||||
|
|
|
@ -37,7 +37,6 @@ import org.mozilla.fenix.IntentReceiverActivity
|
|||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.ext.components
|
||||
import org.mozilla.fenix.settings.PhoneFeature
|
||||
import org.mozilla.fenix.utils.Settings
|
||||
import com.google.android.material.R as MaterialR
|
||||
|
||||
/**
|
||||
|
@ -62,6 +61,7 @@ class QuickSettingsSheetDialogFragment : AppCompatDialogFragment() {
|
|||
savedInstanceState: Bundle?
|
||||
): View {
|
||||
val context = requireContext()
|
||||
val components = context.components
|
||||
val rootView = inflateRootView(container)
|
||||
|
||||
quickSettingsStore = QuickSettingsFragmentStore.createStore(
|
||||
|
@ -70,7 +70,7 @@ class QuickSettingsSheetDialogFragment : AppCompatDialogFragment() {
|
|||
websiteTitle = args.title,
|
||||
isSecured = args.isSecured,
|
||||
permissions = args.sitePermissions,
|
||||
settings = Settings.getInstance(context),
|
||||
settings = components.settings,
|
||||
certificateName = args.certificateName
|
||||
)
|
||||
|
||||
|
@ -79,12 +79,12 @@ class QuickSettingsSheetDialogFragment : AppCompatDialogFragment() {
|
|||
quickSettingsStore = quickSettingsStore,
|
||||
ioScope = viewLifecycleOwner.lifecycleScope + Dispatchers.IO,
|
||||
navController = findNavController(),
|
||||
session = context.components.core.sessionManager.findSessionById(args.sessionId),
|
||||
session = components.core.sessionManager.findSessionById(args.sessionId),
|
||||
sitePermissions = args.sitePermissions,
|
||||
settings = Settings.getInstance(context),
|
||||
permissionStorage = context.components.core.permissionStorage,
|
||||
reload = context.components.useCases.sessionUseCases.reload,
|
||||
addNewTab = context.components.useCases.tabsUseCases.addTab,
|
||||
settings = components.settings,
|
||||
permissionStorage = components.core.permissionStorage,
|
||||
reload = components.useCases.sessionUseCases.reload,
|
||||
addNewTab = components.useCases.tabsUseCases.addTab,
|
||||
requestRuntimePermissions = { permissions ->
|
||||
requestPermissions(permissions, REQUEST_CODE_QUICK_SETTINGS_PERMISSIONS)
|
||||
tryToRequestPermissions = true
|
||||
|
|
|
@ -16,8 +16,10 @@ import androidx.lifecycle.LifecycleCoroutineScope
|
|||
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
||||
import com.google.android.material.tabs.TabLayout
|
||||
import kotlinx.android.extensions.LayoutContainer
|
||||
import kotlinx.android.synthetic.main.component_tabstray.*
|
||||
import kotlinx.android.synthetic.main.component_tabstray.view.*
|
||||
import kotlinx.android.synthetic.main.component_tabstray_fab.view.*
|
||||
import kotlinx.android.synthetic.main.tabs_tray_tab_counter.*
|
||||
import kotlinx.coroutines.Dispatchers.Main
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
|
@ -36,7 +38,7 @@ import org.mozilla.fenix.ext.settings
|
|||
/**
|
||||
* View that contains and configures the BrowserAwesomeBar
|
||||
*/
|
||||
@Suppress("LongParameterList")
|
||||
@Suppress("LongParameterList", "TooManyFunctions", "LargeClass")
|
||||
class TabTrayView(
|
||||
private val container: ViewGroup,
|
||||
private val interactor: TabTrayInteractor,
|
||||
|
@ -245,6 +247,17 @@ class TabTrayView(
|
|||
View.VISIBLE
|
||||
}
|
||||
view.tab_tray_overflow.isVisible = !hasNoTabs
|
||||
|
||||
counter_text.text = "${state.normalTabs.size}"
|
||||
updateTabCounterContentDescription(state.normalTabs.size)
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateTabCounterContentDescription(count: Int) {
|
||||
view.tab_layout.getTabAt(0)?.contentDescription = if (count == 1) {
|
||||
view.context?.getString(R.string.open_tab_tray_single)
|
||||
} else {
|
||||
view.context?.getString(R.string.open_tab_tray_plural, count.toString())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -7,11 +7,11 @@ package org.mozilla.fenix.tabtray
|
|||
import android.view.View
|
||||
import android.view.accessibility.AccessibilityNodeInfo
|
||||
import android.widget.ImageButton
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import androidx.annotation.VisibleForTesting
|
||||
import androidx.appcompat.widget.AppCompatImageButton
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.view.doOnNextLayout
|
||||
import mozilla.components.browser.state.state.MediaState
|
||||
import mozilla.components.browser.tabstray.TabViewHolder
|
||||
import mozilla.components.browser.tabstray.thumbnail.TabThumbnailView
|
||||
|
@ -21,7 +21,7 @@ import mozilla.components.concept.tabstray.TabsTray
|
|||
import mozilla.components.feature.media.ext.pauseIfPlaying
|
||||
import mozilla.components.feature.media.ext.playIfPaused
|
||||
import mozilla.components.support.base.observer.Observable
|
||||
import mozilla.components.support.images.ext.loadIntoView
|
||||
import mozilla.components.support.images.ImageLoadRequest
|
||||
import mozilla.components.support.images.loader.ImageLoader
|
||||
import mozilla.components.support.ktx.kotlin.tryGetHostFromUrl
|
||||
import org.mozilla.fenix.R
|
||||
|
@ -32,6 +32,7 @@ import org.mozilla.fenix.ext.removeAndDisable
|
|||
import org.mozilla.fenix.ext.removeTouchDelegate
|
||||
import org.mozilla.fenix.ext.showAndEnable
|
||||
import org.mozilla.fenix.ext.toTab
|
||||
import kotlin.math.max
|
||||
|
||||
/**
|
||||
* A RecyclerView ViewHolder implementation for "tab" items.
|
||||
|
@ -73,10 +74,7 @@ class TabTrayViewHolder(
|
|||
if (tab.thumbnail != null) {
|
||||
thumbnailView.setImageBitmap(tab.thumbnail)
|
||||
} else {
|
||||
// Make sure we have the view's dimensions so we can load the image at the correct size
|
||||
thumbnailView.doOnNextLayout {
|
||||
imageLoader.loadIntoView(thumbnailView, tab.id)
|
||||
}
|
||||
loadIntoThumbnailView(thumbnailView, tab.id)
|
||||
}
|
||||
|
||||
// Media state
|
||||
|
@ -182,6 +180,14 @@ class TabTrayViewHolder(
|
|||
closeView.context.getString(R.string.close_tab_title, title)
|
||||
}
|
||||
|
||||
private fun loadIntoThumbnailView(thumbnailView: ImageView, id: String) {
|
||||
val thumbnailSize = max(
|
||||
itemView.resources.getDimensionPixelSize(R.dimen.tab_tray_thumbnail_height),
|
||||
itemView.resources.getDimensionPixelSize(R.dimen.tab_tray_thumbnail_width)
|
||||
)
|
||||
imageLoader.loadIntoView(thumbnailView, ImageLoadRequest(id, thumbnailSize))
|
||||
}
|
||||
|
||||
internal fun updateAccessibilityRowIndex(item: View, newIndex: Int) {
|
||||
item.setAccessibilityDelegate(object : View.AccessibilityDelegate() {
|
||||
override fun onInitializeAccessibilityNodeInfo(
|
||||
|
|
|
@ -21,7 +21,7 @@ import kotlinx.android.synthetic.main.tracking_protection_onboarding_popup.view.
|
|||
import mozilla.components.browser.session.Session
|
||||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.components.metrics.Event
|
||||
import org.mozilla.fenix.ext.components
|
||||
import org.mozilla.fenix.components.metrics.MetricController
|
||||
import org.mozilla.fenix.ext.increaseTapArea
|
||||
import org.mozilla.fenix.utils.Settings
|
||||
|
||||
|
@ -32,6 +32,7 @@ import org.mozilla.fenix.utils.Settings
|
|||
class TrackingProtectionOverlay(
|
||||
private val context: Context,
|
||||
private val settings: Settings,
|
||||
private val metrics: MetricController,
|
||||
private val getToolbar: () -> View
|
||||
) : Session.Observer {
|
||||
|
||||
|
@ -54,7 +55,7 @@ class TrackingProtectionOverlay(
|
|||
override fun onTouchEvent(event: MotionEvent): Boolean {
|
||||
|
||||
if (event.action == MotionEvent.ACTION_DOWN) {
|
||||
context.components.analytics.metrics.track(Event.ContextualHintETPOutsideTap)
|
||||
metrics.track(Event.ContextualHintETPOutsideTap)
|
||||
}
|
||||
return super.onTouchEvent(event)
|
||||
}
|
||||
|
@ -62,7 +63,7 @@ class TrackingProtectionOverlay(
|
|||
|
||||
val layout = LayoutInflater.from(context)
|
||||
.inflate(R.layout.tracking_protection_onboarding_popup, null)
|
||||
val isBottomToolbar = Settings.getInstance(context).shouldUseBottomToolbar
|
||||
val isBottomToolbar = settings.shouldUseBottomToolbar
|
||||
|
||||
layout.drop_down_triangle.isGone = isBottomToolbar
|
||||
layout.pop_up_triangle.isVisible = isBottomToolbar
|
||||
|
@ -76,13 +77,13 @@ class TrackingProtectionOverlay(
|
|||
val closeButton = layout.findViewById<ImageView>(R.id.close_onboarding)
|
||||
closeButton.increaseTapArea(BUTTON_INCREASE_DPS)
|
||||
closeButton.setOnClickListener {
|
||||
context.components.analytics.metrics.track(Event.ContextualHintETPDismissed)
|
||||
metrics.track(Event.ContextualHintETPDismissed)
|
||||
trackingOnboardingDialog.dismiss()
|
||||
}
|
||||
|
||||
val res = context.resources
|
||||
val triangleWidthPx = res.getDimension(R.dimen.tp_onboarding_triangle_height)
|
||||
val triangleMarginStartPx = res.getDimension(R.dimen.tp_onboarding_triangle_margin_start)
|
||||
val triangleWidthPx = res.getDimension(R.dimen.cfr_triangle_height)
|
||||
val triangleMarginStartPx = res.getDimension(R.dimen.cfr_triangle_margin_edge)
|
||||
|
||||
val toolbar = getToolbar()
|
||||
val trackingProtectionIcon: View =
|
||||
|
@ -115,12 +116,12 @@ class TrackingProtectionOverlay(
|
|||
val etpShield =
|
||||
getToolbar().findViewById<View>(R.id.mozac_browser_toolbar_tracking_protection_indicator)
|
||||
trackingOnboardingDialog.message.setOnClickListener {
|
||||
context.components.analytics.metrics.track(Event.ContextualHintETPInsideTap)
|
||||
metrics.track(Event.ContextualHintETPInsideTap)
|
||||
trackingOnboardingDialog.dismiss()
|
||||
etpShield.performClick()
|
||||
}
|
||||
|
||||
context.components.analytics.metrics.track(Event.ContextualHintETPDisplayed)
|
||||
metrics.track(Event.ContextualHintETPDisplayed)
|
||||
trackingOnboardingDialog.show()
|
||||
settings.incrementTrackingProtectionOnboardingCount()
|
||||
}
|
||||
|
|
|
@ -33,9 +33,9 @@ import org.mozilla.fenix.ext.components
|
|||
import org.mozilla.fenix.ext.getPreferenceKey
|
||||
import org.mozilla.fenix.settings.PhoneFeature
|
||||
import org.mozilla.fenix.settings.deletebrowsingdata.DeleteBrowsingDataOnQuitType
|
||||
import org.mozilla.fenix.settings.logins.fragment.SavedLoginsFragment
|
||||
import org.mozilla.fenix.settings.logins.SavedLoginsSortingStrategyMenu
|
||||
import org.mozilla.fenix.settings.logins.SortingStrategy
|
||||
import org.mozilla.fenix.settings.logins.fragment.SavedLoginsFragment
|
||||
import org.mozilla.fenix.settings.registerOnSharedPreferenceChangeListener
|
||||
import java.security.InvalidParameterException
|
||||
|
||||
|
@ -43,12 +43,11 @@ private const val AUTOPLAY_USER_SETTING = "AUTOPLAY_USER_SETTING"
|
|||
|
||||
/**
|
||||
* A simple wrapper for SharedPreferences that makes reading preference a little bit easier.
|
||||
* @param appContext Reference to application context.
|
||||
*/
|
||||
@Suppress("LargeClass", "TooManyFunctions")
|
||||
class Settings private constructor(
|
||||
context: Context,
|
||||
private val isCrashReportEnabledInBuild: Boolean
|
||||
) : PreferencesHolder {
|
||||
class Settings(private val appContext: Context) : PreferencesHolder {
|
||||
|
||||
companion object {
|
||||
const val showLoginsSecureWarningSyncMaxCount = 1
|
||||
const val showLoginsSecureWarningMaxCount = 1
|
||||
|
@ -88,24 +87,11 @@ class Settings private constructor(
|
|||
ASK_TO_ALLOW_INT -> AutoplayAction.BLOCKED
|
||||
else -> throw InvalidParameterException("$this is not a valid SitePermissionsRules.AutoplayAction")
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
internal var instance: Settings? = null
|
||||
|
||||
@JvmStatic
|
||||
@Synchronized
|
||||
fun getInstance(
|
||||
context: Context,
|
||||
isCrashReportEnabledInBuild: Boolean = BuildConfig.CRASH_REPORTING && Config.channel.isReleased
|
||||
): Settings {
|
||||
if (instance == null) {
|
||||
instance = Settings(context.applicationContext, isCrashReportEnabledInBuild)
|
||||
}
|
||||
return instance ?: throw AssertionError("Instance cleared")
|
||||
}
|
||||
}
|
||||
|
||||
private val appContext = context.applicationContext
|
||||
@VisibleForTesting
|
||||
internal val isCrashReportEnabledInBuild: Boolean =
|
||||
BuildConfig.CRASH_REPORTING && Config.channel.isReleased
|
||||
|
||||
override val preferences: SharedPreferences =
|
||||
appContext.getSharedPreferences(FENIX_PREFERENCES, MODE_PRIVATE)
|
||||
|
@ -372,7 +358,7 @@ class Settings private constructor(
|
|||
appContext.getPreferenceKey(R.string.pref_key_tracking_protection_standard_option),
|
||||
false
|
||||
).apply()
|
||||
appContext?.components?.let {
|
||||
appContext.components.let {
|
||||
val policy = it.core.trackingProtectionPolicyFactory
|
||||
.createTrackingProtectionPolicy()
|
||||
it.useCases.settingsUseCases.updateTrackingProtection.invoke(policy)
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
<?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/. -->
|
||||
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:fromDegrees="45"
|
||||
android:pivotX="-40%"
|
||||
android:pivotY="87%"
|
||||
android:toDegrees="45">
|
||||
<shape android:shape="rectangle">
|
||||
<stroke
|
||||
android:width="10dp"
|
||||
android:color="#FFFFFF" />
|
||||
<solid android:color="#FFFFFF" />
|
||||
</shape>
|
||||
</rotate>
|
|
@ -1,20 +0,0 @@
|
|||
<?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/. -->
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item>
|
||||
<rotate
|
||||
android:fromDegrees="45"
|
||||
android:pivotX="-40%"
|
||||
android:pivotY="87%"
|
||||
android:toDegrees="45">
|
||||
<shape android:shape="rectangle">
|
||||
<stroke
|
||||
android:width="10dp"
|
||||
android:color="#7542E5" />
|
||||
<solid android:color="#7542E5" />
|
||||
</shape>
|
||||
</rotate>
|
||||
</item>
|
||||
</layer-list>
|
|
@ -1,20 +0,0 @@
|
|||
<?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/. -->
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item>
|
||||
<rotate
|
||||
android:fromDegrees="45"
|
||||
android:pivotX="-40%"
|
||||
android:pivotY="87%"
|
||||
android:toDegrees="45">
|
||||
<shape android:shape="rectangle">
|
||||
<stroke
|
||||
android:width="10dp"
|
||||
android:color="#0250BB" />
|
||||
<solid android:color="#0250BB" />
|
||||
</shape>
|
||||
</rotate>
|
||||
</item>
|
||||
</layer-list>
|
|
@ -46,27 +46,28 @@
|
|||
android:layout_width="0dp"
|
||||
android:layout_height="80dp"
|
||||
android:background="@color/foundation_normal_theme"
|
||||
app:tabIndicatorColor="@color/accent_normal_theme"
|
||||
app:tabIconTint="@color/tab_icon"
|
||||
app:tabRippleColor="@android:color/transparent"
|
||||
app:tabGravity="fill"
|
||||
app:layout_constraintWidth_percent="0.5"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/handle"
|
||||
app:layout_constraintStart_toStartOf="parent">
|
||||
app:layout_constraintWidth_percent="0.5"
|
||||
app:tabGravity="fill"
|
||||
app:tabIconTint="@color/tab_icon"
|
||||
app:tabIndicatorColor="@color/accent_normal_theme"
|
||||
app:tabRippleColor="@android:color/transparent">
|
||||
|
||||
<com.google.android.material.tabs.TabItem
|
||||
android:id="@+id/default_tab_item"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_width="0dp"
|
||||
android:icon="@drawable/ic_tabs"
|
||||
android:contentDescription="@string/tab_header_label" />
|
||||
android:layout_height="match_parent"
|
||||
android:contentDescription="@string/tab_header_label"
|
||||
android:layout="@layout/tabs_tray_tab_counter"
|
||||
app:tabIconTint="@color/tab_icon" />
|
||||
|
||||
<com.google.android.material.tabs.TabItem
|
||||
android:id="@+id/private_tab_item"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_width="0dp"
|
||||
android:icon="@drawable/ic_private_browsing"
|
||||
android:contentDescription="@string/tabs_header_private_tabs_title" />
|
||||
android:layout_height="match_parent"
|
||||
android:contentDescription="@string/tabs_header_private_tabs_title"
|
||||
android:icon="@drawable/ic_private_browsing" />
|
||||
|
||||
</com.google.android.material.tabs.TabLayout>
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
android:background="?android:attr/selectableItemBackground"
|
||||
android:button="@null"
|
||||
app:drawableStartCompat="?android:attr/listChoiceIndicatorSingle"
|
||||
android:drawablePadding="@dimen/preference_seek_bar_padding"
|
||||
android:drawablePadding="@dimen/radio_button_preference_drawable_padding"
|
||||
android:paddingTop="@dimen/radio_button_preference_vertical"
|
||||
android:paddingStart="@dimen/radio_button_preference_horizontal"
|
||||
android:paddingEnd="@dimen/radio_button_preference_horizontal"
|
||||
|
@ -40,7 +40,7 @@
|
|||
android:background="?android:attr/selectableItemBackground"
|
||||
android:button="@null"
|
||||
app:drawableStartCompat="?android:attr/listChoiceIndicatorSingle"
|
||||
android:drawablePadding="@dimen/preference_seek_bar_padding"
|
||||
android:drawablePadding="@dimen/radio_button_preference_drawable_padding"
|
||||
android:paddingTop="@dimen/radio_button_preference_vertical"
|
||||
android:paddingStart="@dimen/radio_button_preference_horizontal"
|
||||
android:paddingEnd="@dimen/radio_button_preference_horizontal"
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:background="?android:attr/selectableItemBackground"
|
||||
android:button="@null"
|
||||
android:drawablePadding="@dimen/preference_seek_bar_padding"
|
||||
android:drawablePadding="@dimen/radio_button_preference_drawable_padding"
|
||||
android:paddingStart="@dimen/radio_button_preference_horizontal"
|
||||
android:paddingTop="@dimen/radio_button_preference_vertical"
|
||||
android:paddingEnd="@dimen/radio_button_preference_horizontal"
|
||||
|
@ -39,7 +39,7 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:background="?android:attr/selectableItemBackground"
|
||||
android:button="@null"
|
||||
android:drawablePadding="@dimen/preference_seek_bar_padding"
|
||||
android:drawablePadding="@dimen/radio_button_preference_drawable_padding"
|
||||
android:paddingStart="@dimen/radio_button_preference_horizontal"
|
||||
android:paddingTop="@dimen/radio_button_preference_vertical"
|
||||
android:paddingEnd="@dimen/radio_button_preference_horizontal"
|
||||
|
@ -54,7 +54,7 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:background="?android:attr/selectableItemBackground"
|
||||
android:button="@null"
|
||||
android:drawablePadding="@dimen/preference_seek_bar_padding"
|
||||
android:drawablePadding="@dimen/radio_button_preference_drawable_padding"
|
||||
android:paddingStart="@dimen/radio_button_preference_horizontal"
|
||||
android:paddingTop="@dimen/radio_button_preference_vertical"
|
||||
android:paddingEnd="@dimen/radio_button_preference_horizontal"
|
||||
|
@ -68,7 +68,7 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:background="?android:attr/selectableItemBackground"
|
||||
android:button="@null"
|
||||
android:drawablePadding="@dimen/preference_seek_bar_padding"
|
||||
android:drawablePadding="@dimen/radio_button_preference_drawable_padding"
|
||||
android:paddingStart="@dimen/radio_button_preference_horizontal"
|
||||
android:paddingTop="@dimen/radio_button_preference_vertical"
|
||||
android:paddingEnd="@dimen/radio_button_preference_horizontal"
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/onboarding_card"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
@ -140,34 +141,18 @@
|
|||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:background="@android:color/transparent"
|
||||
android:contentDescription="@string/onboarding_theme_automatic_title"
|
||||
android:foreground="@drawable/rounded_ripple"
|
||||
android:paddingStart="0dp"
|
||||
android:paddingEnd="8dp"
|
||||
android:theme="@style/Checkable.Colored"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/divider"
|
||||
app:onboardingKey="@string/pref_key_follow_device_theme" />
|
||||
app:onboardingKey="@string/pref_key_follow_device_theme"
|
||||
app:onboardingKeyDescription="@string/onboarding_theme_automatic_summary"
|
||||
app:onboardingKeyTitle="@string/onboarding_theme_automatic_title"
|
||||
tools:text="Automatic" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/automatic_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="9dp"
|
||||
android:text="@string/onboarding_theme_automatic_title"
|
||||
android:textColor="?primaryText"
|
||||
android:textSize="16sp"
|
||||
app:layout_constraintStart_toEndOf="@+id/theme_automatic_radio_button"
|
||||
app:layout_constraintTop_toBottomOf="@+id/divider" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/automatic_theme_summary"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/onboarding_theme_automatic_summary"
|
||||
android:textColor="?secondaryText"
|
||||
android:textSize="14sp"
|
||||
app:layout_constraintStart_toEndOf="@+id/theme_automatic_radio_button"
|
||||
app:layout_constraintEnd_toEndOf="@id/clickable_region_automatic"
|
||||
app:layout_constraintTop_toBottomOf="@id/automatic_title" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
|
|
@ -7,7 +7,9 @@
|
|||
android:id="@+id/onboarding_card"
|
||||
style="@style/OnboardingCardLightWithPadding"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
android:layout_height="wrap_content"
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/header_text"
|
||||
|
@ -44,97 +46,48 @@
|
|||
app:layout_constraintTop_toBottomOf="@id/header_text"
|
||||
tools:text="@string/onboarding_tracking_protection_description_2" />
|
||||
|
||||
<View
|
||||
android:id="@+id/clickable_region_standard"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:foreground="@drawable/rounded_ripple"
|
||||
app:layout_constraintBottom_toBottomOf="@id/protection_standard_description"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@id/tracking_protection_standard_option" />
|
||||
|
||||
<org.mozilla.fenix.onboarding.OnboardingRadioButton
|
||||
android:id="@+id/tracking_protection_standard_option"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:paddingStart="0dp"
|
||||
android:paddingEnd="8dp"
|
||||
android:background="@android:color/transparent"
|
||||
android:checked="true"
|
||||
android:foreground="@drawable/rounded_ripple"
|
||||
android:gravity="top"
|
||||
android:paddingStart="8dp"
|
||||
android:paddingEnd="8dp"
|
||||
android:theme="@style/Checkable.Colored"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/description_text"
|
||||
app:onboardingKey="@string/pref_key_tracking_protection_standard_option" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/protection_standard_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/onboarding_tracking_protection_standard_button_2"
|
||||
android:textColor="@color/primary_state_list_text_color"
|
||||
android:textSize="16sp"
|
||||
app:layout_constraintStart_toEndOf="@+id/tracking_protection_standard_option"
|
||||
app:layout_constraintTop_toTopOf="@+id/tracking_protection_standard_option" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/protection_standard_description"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/onboarding_tracking_protection_standard_button_description_2"
|
||||
android:textColor="@color/secondary_state_list_text_color"
|
||||
android:textSize="14sp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="@+id/protection_standard_title"
|
||||
app:layout_constraintTop_toBottomOf="@id/protection_standard_title" />
|
||||
|
||||
<View
|
||||
android:id="@+id/clickable_region_strict"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:foreground="@drawable/rounded_ripple"
|
||||
app:layout_constraintBottom_toBottomOf="@id/protection_strict_description"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@id/tracking_protection_strict_default" />
|
||||
app:onboardingKey="@string/pref_key_tracking_protection_standard_option"
|
||||
app:onboardingKeyDescription="@string/onboarding_tracking_protection_standard_button_description_2"
|
||||
app:onboardingKeyTitle="@string/onboarding_tracking_protection_standard_button_2"
|
||||
tools:text="Standard" />
|
||||
|
||||
<org.mozilla.fenix.onboarding.OnboardingRadioButton
|
||||
android:id="@+id/tracking_protection_strict_default"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:background="@android:color/transparent"
|
||||
android:checked="false"
|
||||
android:paddingStart="0dp"
|
||||
android:foreground="@drawable/rounded_ripple"
|
||||
android:gravity="top"
|
||||
android:paddingStart="8dp"
|
||||
android:paddingEnd="8dp"
|
||||
android:textColor="@color/primary_state_list_text_color"
|
||||
android:theme="@style/Checkable.Colored"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/tracking_protection_standard_option"
|
||||
app:onboardingKey="@string/pref_key_tracking_protection_strict_default" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/protection_strict_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/onboarding_tracking_protection_strict_option"
|
||||
android:textColor="@color/primary_state_list_text_color"
|
||||
android:textSize="16sp"
|
||||
app:layout_constraintStart_toEndOf="@+id/tracking_protection_strict_default"
|
||||
app:layout_constraintTop_toTopOf="@+id/tracking_protection_strict_default" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/protection_strict_description"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/onboarding_tracking_protection_strict_button_description_2"
|
||||
android:textColor="@color/secondary_state_list_text_color"
|
||||
android:textSize="14sp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="@+id/protection_strict_title"
|
||||
app:layout_constraintTop_toBottomOf="@id/protection_strict_title" />
|
||||
app:onboardingKey="@string/pref_key_tracking_protection_strict_default"
|
||||
app:onboardingKeyDescription="@string/onboarding_tracking_protection_strict_button_description_2"
|
||||
app:onboardingKeyTitle="@string/onboarding_tracking_protection_strict_option"
|
||||
tools:text="Strict" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
|
|
@ -9,12 +9,13 @@
|
|||
android:orientation="vertical">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="16dp"
|
||||
android:layout_height="16dp"
|
||||
android:layout_width="@dimen/cfr_triangle_width"
|
||||
android:layout_height="@dimen/cfr_triangle_height"
|
||||
android:layout_gravity="end"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginEnd="@dimen/cfr_triangle_margin_edge"
|
||||
android:importantForAccessibility="no"
|
||||
app:srcCompat="@drawable/ic_pbm_triangle" />
|
||||
app:srcCompat="@drawable/ic_cfr_triangle"
|
||||
app:tint="#7542E5" />
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
|
|
|
@ -13,11 +13,12 @@
|
|||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:visibility="gone"
|
||||
android:id="@+id/drop_down_triangle"
|
||||
android:layout_width="@dimen/tp_onboarding_triangle_width"
|
||||
android:layout_height="@dimen/tp_onboarding_triangle_height"
|
||||
android:layout_width="@dimen/cfr_triangle_width"
|
||||
android:layout_height="@dimen/cfr_triangle_height"
|
||||
android:importantForAccessibility="no"
|
||||
android:rotation="0"
|
||||
app:srcCompat="@drawable/ic_pbm_triangle"
|
||||
app:srcCompat="@drawable/ic_cfr_triangle"
|
||||
app:tint="#7542E5"
|
||||
android:layout_gravity="center" />
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
|
@ -92,9 +93,10 @@
|
|||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/pop_up_triangle"
|
||||
android:layout_width="16dp"
|
||||
android:layout_height="@dimen/tp_onboarding_triangle_height"
|
||||
android:layout_height="@dimen/cfr_triangle_height"
|
||||
android:importantForAccessibility="no"
|
||||
android:rotation="180"
|
||||
app:srcCompat="@drawable/ic_pbm_triangle"
|
||||
app:srcCompat="@drawable/ic_cfr_triangle"
|
||||
app:tint="#7542E5"
|
||||
android:layout_gravity="center" />
|
||||
</LinearLayout>
|
||||
|
|
|
@ -25,8 +25,8 @@
|
|||
|
||||
<androidx.cardview.widget.CardView
|
||||
android:id="@+id/mozac_browser_tabstray_card"
|
||||
android:layout_width="92dp"
|
||||
android:layout_height="69dp"
|
||||
android:layout_width="@dimen/tab_tray_thumbnail_width"
|
||||
android:layout_height="@dimen/tab_tray_thumbnail_height"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:backgroundTint="?tabTrayThumbnailItemBackground"
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
<?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/. -->
|
||||
<FrameLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/counter_root"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_centerVertical="true">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/counter_box"
|
||||
android:layout_width="@dimen/tab_counter_box_width_height"
|
||||
android:layout_height="@dimen/tab_counter_box_width_height"
|
||||
android:importantForAccessibility="no"
|
||||
app:tint="@color/tab_icon"
|
||||
app:srcCompat="@drawable/ic_tabs"/>
|
||||
|
||||
<!-- This text size auto adjusts based on num digits in `TabCounter` -->
|
||||
<TextView
|
||||
android:id="@+id/counter_text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:textAlignment="center"
|
||||
android:textColor="@color/tab_icon"
|
||||
android:textSize="12sp"
|
||||
android:textStyle="bold"
|
||||
tools:text="16" />
|
||||
</FrameLayout>
|
|
@ -11,12 +11,13 @@
|
|||
<ImageView
|
||||
android:visibility="gone"
|
||||
android:id="@+id/drop_down_triangle"
|
||||
android:layout_width="@dimen/tp_onboarding_triangle_width"
|
||||
android:layout_height="@dimen/tp_onboarding_triangle_height"
|
||||
android:layout_marginStart="@dimen/tp_onboarding_triangle_margin_start"
|
||||
android:layout_width="@dimen/cfr_triangle_width"
|
||||
android:layout_height="@dimen/cfr_triangle_height"
|
||||
android:layout_marginStart="@dimen/cfr_triangle_margin_edge"
|
||||
android:importantForAccessibility="no"
|
||||
android:rotation="0"
|
||||
app:srcCompat="@drawable/ic_triangle"
|
||||
app:srcCompat="@drawable/ic_cfr_triangle"
|
||||
app:tint="#0250BB"
|
||||
android:layout_gravity="start" />
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
|
@ -36,7 +37,7 @@
|
|||
android:focusable="true"
|
||||
android:contentDescription="@string/onboarding_close"
|
||||
app:srcCompat="@drawable/ic_close"
|
||||
android:tint="@color/primary_text_dark_theme"
|
||||
app:tint="@color/primary_text_dark_theme"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
|
@ -60,11 +61,12 @@
|
|||
|
||||
<ImageView
|
||||
android:id="@+id/pop_up_triangle"
|
||||
android:layout_width="16dp"
|
||||
android:layout_height="@dimen/tp_onboarding_triangle_height"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_width="@dimen/cfr_triangle_width"
|
||||
android:layout_height="@dimen/cfr_triangle_height"
|
||||
android:layout_marginStart="@dimen/cfr_triangle_margin_edge"
|
||||
android:importantForAccessibility="no"
|
||||
android:rotation="180"
|
||||
app:srcCompat="@drawable/ic_triangle"
|
||||
app:srcCompat="@drawable/ic_cfr_triangle"
|
||||
app:tint="#0250BB"
|
||||
android:layout_gravity="start" />
|
||||
</LinearLayout>
|
||||
|
|
|
@ -78,7 +78,7 @@
|
|||
<!-- Browser menu button that opens the addon manager -->
|
||||
<string name="browser_menu_add_ons">Askouezhioù</string>
|
||||
<!-- Text displayed when there are no add-ons to be shown -->
|
||||
<string name="no_add_ons">Nʼeus tamm enlugellad ebet amañ</string>
|
||||
<string name="no_add_ons">Nʼeus tamm askouezh ebet amañ</string>
|
||||
<!-- Browser menu button that sends a user to help articles -->
|
||||
<string name="browser_menu_help">Skoazell</string>
|
||||
<!-- Browser menu button that sends a to a the what's new article -->
|
||||
|
@ -296,7 +296,7 @@
|
|||
<!-- Text shown when user enters empty device name -->
|
||||
<string name="empty_device_name_error">Anv an trevnad nʼhall ket bezañ goullo.</string>
|
||||
<!-- Label indicating that sync is in progress -->
|
||||
<string name="sync_syncing_in_progress">O goubredañ...</string>
|
||||
<string name="sync_syncing_in_progress">O c’houbredañ...</string>
|
||||
<!-- Label summary indicating that sync failed. The first parameter is the date stamp showing last time it succeeded -->
|
||||
<string name="sync_failed_summary">Goubredañ cʼhwitet. Berzh diwezhañ: %s</string>
|
||||
|
||||
|
@ -390,7 +390,7 @@
|
|||
<!-- Preference for using top toolbar -->
|
||||
<string name="preference_top_toolbar">Krecʼh</string>
|
||||
<!-- Preference for using bottom toolbar -->
|
||||
<string name="preference_bottom_toolbar">Diaz</string>
|
||||
<string name="preference_bottom_toolbar">Traoñ</string>
|
||||
|
||||
<!-- Theme Preferences -->
|
||||
<!-- Preference for using light theme -->
|
||||
|
@ -398,7 +398,7 @@
|
|||
<!-- Preference for using dark theme -->
|
||||
<string name="preference_dark_theme">Teñval</string>
|
||||
<!-- Preference for using using dark or light theme automatically set by battery -->
|
||||
<string name="preference_auto_battery_theme">Lakaet gant an esperner tredan</string>
|
||||
<string name="preference_auto_battery_theme">Dibabet gant an esperner tredan</string>
|
||||
<!-- Preference for using following device theme -->
|
||||
<string name="preference_follow_device_theme">Mont gant neuz ar benveg</string>
|
||||
|
||||
|
@ -474,7 +474,7 @@
|
|||
<!-- Open tabs menu item to share all tabs -->
|
||||
<string name="tabs_menu_share_tabs">Rannañ an ivinelloù</string>
|
||||
<!-- Open tabs menu item to save tabs to collection -->
|
||||
<string name="tabs_menu_save_to_collection1">Enrollañ an ivinelloù en dastumad</string>
|
||||
<string name="tabs_menu_save_to_collection1">Enrollañ an ivinelloù en un dastumad</string>
|
||||
|
||||
<!-- Content description (not visible, for screen readers etc.): Opens the tab menu when pressed -->
|
||||
<string name="tab_menu">Lañser an ivinell</string>
|
||||
|
@ -690,7 +690,7 @@
|
|||
<!-- Content description (not visible, for screen readers etc.): Opens the collection menu when pressed -->
|
||||
<string name="collection_menu_button_content_description">Lañser an dastumadoù</string>
|
||||
<!-- No Open Tabs Message Header -->
|
||||
<string name="no_collections_header1">Dastumit ar pezh a gont evidocʼh</string>
|
||||
<string name="no_collections_header1">Dastumit ar pezh a zo pouezus evidoc‘h</string>
|
||||
<!-- Label to describe what collections are to a new user without any collections -->
|
||||
<string name="no_collections_description1">Strollit ar cʼhlaskoù, al lecʼhiennoù hag an ivinelloù heñvel evit mont daveto buanocʼh.</string>
|
||||
<!-- Title for the "select tabs" step of the collection creator -->
|
||||
|
@ -863,7 +863,7 @@
|
|||
<!-- Title for the cached images and files item in Delete browsing data -->
|
||||
<string name="preferences_delete_browsing_data_cached_files">Skeudennoù ha restroù er c’hrubuilh</string>
|
||||
<!-- Subtitle for the cached images and files item in Delete browsing data -->
|
||||
<string name="preferences_delete_browsing_data_cached_files_subtitle">Dieubiñ a ra egor kadaviñ</string>
|
||||
<string name="preferences_delete_browsing_data_cached_files_subtitle">Dieubiñ a raio egor kadaviñ</string>
|
||||
|
||||
<!-- Title for the site permissions item in Delete browsing data -->
|
||||
<string name="preferences_delete_browsing_data_site_permissions">Aotreoù al lec’hienn</string>
|
||||
|
@ -1170,7 +1170,7 @@
|
|||
<string name="browser_toolbar_url_copied_to_clipboard_snackbar">URL eilet er golver</string>
|
||||
|
||||
<!-- Title text for the Add To Homescreen dialog -->
|
||||
<string name="add_to_homescreen_title">Ouzhpennañ dʼar skramm degemer</string>
|
||||
<string name="add_to_homescreen_title">Lakaat er skramm degemer</string>
|
||||
<!-- Cancel button text for the Add to Homescreen dialog -->
|
||||
<string name="add_to_homescreen_cancel">Nullañ</string>
|
||||
<!-- Add button text for the Add to Homescreen dialog -->
|
||||
|
@ -1365,7 +1365,7 @@
|
|||
<!-- Bookmark deletion confirmation -->
|
||||
<string name="bookmark_deletion_confirmation">Ha fellout a ra deocʼh dilemel ar sined-mañ ?</string>
|
||||
<!-- Browser menu button that adds a top site to the home fragment -->
|
||||
<string name="browser_menu_add_to_top_sites">Ouzhpennañ dʼal lecʼhiennoù gwellañ</string>
|
||||
<string name="browser_menu_add_to_top_sites">Lakaat el lecʼhiennoù gwellañ</string>
|
||||
<!-- text shown before the issuer name to indicate who its verified by, parameter is the name of
|
||||
the certificate authority that verified the ticket-->
|
||||
<string name="certificate_info_verified_by">Gwiriet gant:%1$s</string>
|
||||
|
|
|
@ -919,6 +919,20 @@
|
|||
<!-- text for firefox preview moving tip header. "Firefox Nightly" is intentionally hardcoded -->
|
||||
<string name="tip_firefox_preview_moved_header_preview_installed">Firefox Nightly हलले आहे</string>
|
||||
|
||||
<!-- text for firefox preview moving tip description -->
|
||||
<string name="tip_firefox_preview_moved_description_preview_installed">या अॅपला यापुढे सुरक्षा अद्यतने प्राप्त होणार नाहीत. हे अॅप वापरणे थांबवा आणि नवीन Nightly वर स्विच करा.
|
||||
\n\nआपल्या वाचनखुणा, लॉगिन, आणि इतिहास इतर अॅप वर स्थानांतरित करण्यासाठी, एक Firefox खाते त.ार करा.</string>
|
||||
<!-- text for firefox preview moving tip button -->
|
||||
<string name="tip_firefox_preview_moved_button_preview_installed">नवीन Nightly वर स्विच करा</string>
|
||||
|
||||
<!-- text for firefox preview moving tip header. "Firefox Nightly" is intentionally hardcoded -->
|
||||
<string name="tip_firefox_preview_moved_header_preview_not_installed">Firefox Nightly हलले आहे</string>
|
||||
<!-- text for firefox preview moving tip description -->
|
||||
<string name="tip_firefox_preview_moved_description_preview_not_installed">या अॅपला यापुढे सुरक्षा अद्यतने प्राप्त होणार नाहीत. नवीन Nightly मिळवा आणि हे अॅप वापरणे थांबवा.
|
||||
\n\nआपल्या वाचनखुणा, लॉगिन, आणि इतिहास इतर अॅप वर स्थानांतरित करण्यासाठी, एक Firefox खाते त.ार करा.</string>
|
||||
<!-- text for firefox preview moving tip button -->
|
||||
<string name="tip_firefox_preview_moved_button_preview_not_installed">नवीन Nightly मिळवा</string>
|
||||
|
||||
<!-- Onboarding -->
|
||||
<!-- Text for onboarding welcome message
|
||||
The first parameter is the name of the app (e.g. Firefox Preview) -->
|
||||
|
@ -954,6 +968,8 @@
|
|||
<string name="onboarding_firefox_account_sync_is_on">सिंक चालू आहे</string>
|
||||
<!-- text to display in the snackbar if automatic sign-in fails. user may try again -->
|
||||
<string name="onboarding_firefox_account_automatic_signin_failed">साइन इन करण्यात अयशस्वी</string>
|
||||
<!-- text for the tracking protection onboarding card header -->
|
||||
<string name="onboarding_tracking_protection_header_2">स्वयंचलित गोपनीयता</string>
|
||||
<!-- text for tracking protection radio button option for strict level of blocking -->
|
||||
<string name="onboarding_tracking_protection_strict_button">कठोर (सुचवलेले)</string>
|
||||
<!-- text for the toolbar position card header
|
||||
|
|
|
@ -16,6 +16,13 @@
|
|||
<!-- No Open Tabs Message Description -->
|
||||
<string name="no_open_tabs_description">Filele deschise vor fi afișate aici.</string>
|
||||
|
||||
<!-- No Private Tabs Message Description -->
|
||||
<string name="no_private_tabs_description">Aici vor fi afișate filele tale private.</string>
|
||||
<!-- Message announced to the user when tab tray is selected with 1 tab -->
|
||||
<string name="open_tab_tray_single">1 filă deschisă. Atinge pentru a comuta filele.</string>
|
||||
<!-- Message announced to the user when tab tray is selected with 0 or 2+ tabs -->
|
||||
<string name="open_tab_tray_plural">%1$s file deschise. Atinge pentru a comuta filele.</string>
|
||||
|
||||
<!-- About content. The first parameter is the name of the application. (For example: Fenix) -->
|
||||
<string name="about_content">%1$s este realizat de Mozilla.</string>
|
||||
|
||||
|
@ -38,6 +45,9 @@
|
|||
<!-- Text for the negative button -->
|
||||
<string name="cfr_neg_button_text">Nu, mulțumesc</string>
|
||||
|
||||
<!-- Search widget "contextual feature recommendation" (CFR) -->
|
||||
<!-- Text for the main message. 'Firefox' intentionally hardcoded here.-->
|
||||
<string name="search_widget_cfr_message">Accesează Firefox mai repede. Adaugă un widget pe ecranul de start.</string>
|
||||
<!-- Text for the positive button -->
|
||||
<string name="search_widget_cfr_pos_button_text">Adaugă widget</string>
|
||||
<!-- Text for the negative button -->
|
||||
|
@ -110,6 +120,8 @@
|
|||
<string name="browser_menu_powered_by2">Cu tehnologie %1$s</string>
|
||||
<!-- Browser menu button to put the current page in reader mode -->
|
||||
<string name="browser_menu_read">Mod de lectură</string>
|
||||
<!-- Browser menu button content description to close reader mode and return the user to the regular browser -->
|
||||
<string name="browser_menu_read_close">Închide modul de lectură</string>
|
||||
<!-- Browser menu button to open the current page in an external app -->
|
||||
<string name="browser_menu_open_app_link">Deschide în aplicație</string>
|
||||
<!-- Browser menu button to configure reader mode appearance e.g. the used font type and size -->
|
||||
|
@ -251,6 +263,8 @@
|
|||
<string name="preferences_show_search_shortcuts">Afișează comenzile rapide pentru căutări</string>
|
||||
<!-- Preference title for switch preference to show search suggestions -->
|
||||
<string name="preferences_show_search_suggestions">Afișează sugestii de căutare</string>
|
||||
<!-- Preference title for switch preference to show voice search button -->
|
||||
<string name="preferences_show_voice_search">Afișează căutarea vocală</string>
|
||||
<!-- Preference title for switch preference to show search suggestions also in private mode -->
|
||||
<string name="preferences_show_search_suggestions_in_private">Afișează în sesiuni private</string>
|
||||
<!-- Preference title for switch preference to show a clipboard suggestion when searching -->
|
||||
|
@ -367,6 +381,9 @@
|
|||
<!-- Preference for removing FxA account -->
|
||||
<string name="preferences_sync_remove_account">Șterge contul</string>
|
||||
|
||||
<!-- Pairing Feature strings -->
|
||||
<!-- Instructions on how to access pairing -->
|
||||
<string name="pair_instructions_2"><![CDATA[Scanează codul QR afișat pe <b>firefox.com/pair</b>]]></string>
|
||||
<!-- Button to open camera for pairing -->
|
||||
<string name="pair_open_camera">Cameră deschisă</string>
|
||||
<!-- Button to cancel pairing -->
|
||||
|
@ -408,6 +425,8 @@
|
|||
<!-- Option in Library to open History page -->
|
||||
<string name="library_history">Istoric</string>
|
||||
|
||||
<!-- Option in Library to open Synced Tabs page -->
|
||||
<string name="library_synced_tabs">File sincronizate</string>
|
||||
<!-- Option in Library to open Reading List -->
|
||||
<string name="library_reading_list">Listă de lectură</string>
|
||||
<!-- Menu Item Label for Search in Library -->
|
||||
|
@ -430,6 +449,24 @@
|
|||
<string name="add_tab">Adaugă fila</string>
|
||||
<!-- Content description (not visible, for screen readers etc.): Add tab button. Adds a news tab when pressed -->
|
||||
<string name="add_private_tab">Adaugă filă privată</string>
|
||||
<!-- Text for the new tab button to indicate adding a new private tab in the tab -->
|
||||
<string name="tab_drawer_fab_content">Privată</string>
|
||||
<!-- Text shown as the title of the open tab tray -->
|
||||
<string name="tab_tray_title">File deschise</string>
|
||||
<!-- Text shown in the menu for saving tabs to a collection -->
|
||||
<string name="tab_tray_menu_item_save">Salvează în colecție</string>
|
||||
<!-- Text shown in the menu for sharing all tabs -->
|
||||
<string name="tab_tray_menu_item_share">Partajează toate filele</string>
|
||||
<!-- Text shown in the menu for closing all tabs -->
|
||||
<string name="tab_tray_menu_item_close">Închide toate filele</string>
|
||||
<!-- Shortcut action to open new tab -->
|
||||
<string name="tab_tray_menu_open_new_tab">Filă nouă</string>
|
||||
<!-- Shortcut action to open the home screen -->
|
||||
<string name="tab_tray_menu_home">Acasă</string>
|
||||
<!-- Shortcut action to toggle private mode -->
|
||||
<string name="tab_tray_menu_toggle">Mod de comutare a filelor</string>
|
||||
<!-- Content description (not visible, for screen readers etc.): Removes tab from collection button. Removes the selected tab from collection when pressed -->
|
||||
<string name="remove_tab_from_collection">Elimină fila din colecție</string>
|
||||
<!-- Content description (not visible, for screen readers etc.): Close tab button. Closes the current session when pressed -->
|
||||
<string name="close_tab">Închide fila</string>
|
||||
<!-- Content description (not visible, for screen readers etc.): Close tab <title> button. First parameter is tab title -->
|
||||
|
@ -440,6 +477,8 @@
|
|||
<string name="tabs_menu_close_all_tabs">Închide toate filele</string>
|
||||
<!-- Open tabs menu item to share all tabs -->
|
||||
<string name="tabs_menu_share_tabs">Partajează filele</string>
|
||||
<!-- Open tabs menu item to save tabs to collection -->
|
||||
<string name="tabs_menu_save_to_collection1">Salvează filele în colecție</string>
|
||||
<!-- Content description (not visible, for screen readers etc.): Opens the tab menu when pressed -->
|
||||
<string name="tab_menu">Meniu de file</string>
|
||||
<!-- Tab menu item to share the tab -->
|
||||
|
@ -463,6 +502,9 @@
|
|||
<!-- Text for the menu button to remove a top site -->
|
||||
<string name="remove_top_site">Șterge</string>
|
||||
|
||||
<!-- Postfix for private WebApp titles, placeholder is replaced with app name -->
|
||||
<string name="pwa_site_controls_title_private">%1$s (mod privat)</string>
|
||||
|
||||
<!-- History -->
|
||||
<!-- Text for the button to clear all history -->
|
||||
<string name="history_delete_all">Șterge istoricul</string>
|
||||
|
@ -652,6 +694,10 @@
|
|||
<!-- Content description (not visible, for screen readers etc.): Opens the collection menu when pressed -->
|
||||
<string name="collection_menu_button_content_description">Meniu de colecții</string>
|
||||
|
||||
<!-- No Open Tabs Message Header -->
|
||||
<string name="no_collections_header1">Colectează ce te interesează</string>
|
||||
<!-- Label to describe what collections are to a new user without any collections -->
|
||||
<string name="no_collections_description1">Grupează căutările similare, site-urile și filele pentru acces mai rapid ulterior.</string>
|
||||
<!-- Title for the "select tabs" step of the collection creator -->
|
||||
<string name="create_collection_select_tabs">Selectează filele</string>
|
||||
<!-- Title for the "select collection" step of the collection creator -->
|
||||
|
@ -681,6 +727,9 @@
|
|||
<!-- Button to save currently selected tabs in the "select tabs" step of the collection creator-->
|
||||
<string name="create_collection_save">Salvează</string>
|
||||
|
||||
<!-- Snackbar action to view the collection the user just created or updated -->
|
||||
<string name="create_collection_view">Afișează</string>
|
||||
|
||||
<!-- Default name for a new collection in "name new collection" step of the collection creator. %d is a placeholder for the number of collections-->
|
||||
<string name="create_collection_default_name">Colecția %d</string>
|
||||
|
||||
|
@ -791,11 +840,15 @@
|
|||
<!-- Title for Accessibility Text Size Scaling Preference -->
|
||||
<string name="preference_accessibility_font_size_title">Dimensiunea fontului</string>
|
||||
|
||||
<!-- Title for Accessibility Text Automatic Size Scaling Preference -->
|
||||
<string name="preference_accessibility_auto_size_2">Mărime automată a fontului</string>
|
||||
<!-- Summary for Accessibility Text Automatic Size Scaling Preference -->
|
||||
<string name="preference_accessibility_auto_size_summary">Dimensiunea fontului va coincide cu cea din setările Android. Dezactivează pentru a gestiona aici dimensiunea fontului.</string>
|
||||
|
||||
<!-- Title for the Delete browsing data preference -->
|
||||
<string name="preferences_delete_browsing_data">Șterge datele de navigare</string>
|
||||
<!-- Title for the tabs item in Delete browsing data -->
|
||||
<string name="preferences_delete_browsing_data_tabs_title_2">File deschise</string>
|
||||
<!-- Subtitle for the tabs item in Delete browsing data, parameter will be replaced with the number of open tabs -->
|
||||
<string name="preferences_delete_browsing_data_tabs_subtitle">%d (de) file</string>
|
||||
|
||||
|
@ -827,8 +880,6 @@
|
|||
<string name="preference_summary_delete_browsing_data_on_quit">Șterge automat datele de navigare când selectezi „Închide” în meniul principal</string>
|
||||
<!-- Summary for the Delete browsing data on quit preference. "Quit" translation should match delete_browsing_data_on_quit_action translation. -->
|
||||
<string name="preference_summary_delete_browsing_data_on_quit_2">Șterge automat datele de navigare când selectezi \„Închide\” în meniul principal</string>
|
||||
<!-- Category for history items to delete on quit in delete browsing data on quit -->
|
||||
<string name="preferences_delete_browsing_data_on_quit_browsing_history">Istoric de navigare</string>
|
||||
<!-- Action item in menu for the Delete browsing data on quit feature -->
|
||||
<string name="delete_browsing_data_on_quit_action">Închide</string>
|
||||
|
||||
|
@ -852,6 +903,9 @@
|
|||
<string name="tip_firefox_preview_moved_description">Firefox Nightly se actualizează în fiecare seară și are funcționalități experimentale noi
|
||||
Dar poate fi mai puțin stabil. Descarcă browserul nostru beta pentru o experiență mai stabilă.</string>
|
||||
|
||||
<!-- text for firefox preview moving tip button. "Firefox for Android Beta" is intentionally hardcoded -->
|
||||
<string name="tip_firefox_preview_moved_button_2">Descarcă Firefox Beta pentru Android</string>
|
||||
|
||||
<!-- text for firefox preview moving tip header. "Firefox Nightly" is intentionally hardcoded -->
|
||||
<string name="tip_firefox_preview_moved_header_preview_installed">Firefox Nightly s-a mutat</string>
|
||||
<!-- text for firefox preview moving tip description -->
|
||||
|
@ -903,8 +957,21 @@
|
|||
<string name="onboarding_firefox_account_sync_is_on">Sync este activat</string>
|
||||
<!-- text to display in the snackbar if automatic sign-in fails. user may try again -->
|
||||
<string name="onboarding_firefox_account_automatic_signin_failed">Eroare de autentificare</string>
|
||||
<!-- text for the tracking protection onboarding card header -->
|
||||
<string name="onboarding_tracking_protection_header_2">Confidențialitate automată</string>
|
||||
<!-- text for the tracking protection card description
|
||||
The first parameter is the name of the app (e.g. Firefox Preview) -->
|
||||
<string name="onboarding_tracking_protection_description_2">Setările de confidențialitate și securitate blochează elementele de urmărire, softurile rău-intenționate și firmele care te urmăresc.</string>
|
||||
<!-- text for tracking protection radio button option for standard level of blocking -->
|
||||
<string name="onboarding_tracking_protection_standard_button_2">Standard (implicit)</string>
|
||||
<!-- text for standard blocking option button description -->
|
||||
<string name="onboarding_tracking_protection_standard_button_description_2">Blochează mai puține elemente de urmărire. Paginile se vor încărca normal.</string>
|
||||
<!-- text for tracking protection radio button option for strict level of blocking -->
|
||||
<string name="onboarding_tracking_protection_strict_button">Strictă (recomandat)</string>
|
||||
<!-- text for tracking protection radio button option for strict level of blocking -->
|
||||
<string name="onboarding_tracking_protection_strict_option">Strictă</string>
|
||||
<!-- text for strict blocking option button description -->
|
||||
<string name="onboarding_tracking_protection_strict_button_description_2">Blochează mai multe elemente de urmărire, reclame și ferestre pop-up. Paginile se încarcă mai repede, dar se poate ca unele funcționalități să nu meargă.</string>
|
||||
<!-- text for the toolbar position card header
|
||||
In English this is an idiom for "choose a side as in an argument or fight"
|
||||
but it is ok to make this more literally about "choosing a position in a physical space -->
|
||||
|
@ -991,14 +1058,22 @@
|
|||
<string name="preference_enhanced_tracking_protection_explanation">Păstrează-ți datele pentru tine. %s te protejează de multe dintre cele mai frecvente elemente de urmărire care monitorizează ce faci online.</string>
|
||||
<!-- Text displayed that links to website about enhanced tracking protection -->
|
||||
<string name="preference_enhanced_tracking_protection_explanation_learn_more">Află mai multe</string>
|
||||
<!-- Preference for enhanced tracking protection for the standard protection settings -->
|
||||
<string name="preference_enhanced_tracking_protection_standard_default_1">Standard (implicit)</string>
|
||||
<!-- Preference description for enhanced tracking protection for the standard protection settings -->
|
||||
<string name="preference_enhanced_tracking_protection_standard_description_3">Blochează mai puține elemente de urmărire. Paginile se vor încărca normal.</string>
|
||||
<!-- Accessibility text for the Standard protection information icon -->
|
||||
<string name="preference_enhanced_tracking_protection_standard_info_button">Ce blochează protecția standard împotriva urmăririi</string>
|
||||
<!-- Preference for enhanced tracking protection for the strict protection settings -->
|
||||
<string name="preference_enhanced_tracking_protection_strict">Strictă</string>
|
||||
<!-- Preference description for enhanced tracking protection for the strict protection settings -->
|
||||
<string name="preference_enhanced_tracking_protection_strict_description_2">Blochează mai multe elemente de urmărire, reclame și ferestre pop-up. Paginile se încarcă mai repede, dar se poate ca unele funcționalități să nu meargă.</string>
|
||||
<!-- Accessibility text for the Strict protection information icon -->
|
||||
<string name="preference_enhanced_tracking_protection_strict_info_button">Ce blochează protecția strictă împotriva urmăririi</string>
|
||||
<!-- Preference for enhanced tracking protection for the custom protection settings -->
|
||||
<string name="preference_enhanced_tracking_protection_custom">Personalizat</string>
|
||||
<!-- Preference description for enhanced tracking protection for the strict protection settings -->
|
||||
<string name="preference_enhanced_tracking_protection_custom_description_2">Alege ce elemente de urmărire și scripturi să blochezi.</string>
|
||||
<!-- Accessibility text for the Strict protection information icon -->
|
||||
<string name="preference_enhanced_tracking_protection_custom_info_button">Ce blochează protecția personalizată împotriva urmăririi</string>
|
||||
<!-- Header for categories that are being blocked by current Enhanced Tracking Protection settings -->
|
||||
|
@ -1048,6 +1123,8 @@
|
|||
|
||||
<!-- Description of tracking content that can be blocked by Enhanced Tracking Protection -->
|
||||
<string name="etp_tracking_content_description">Oprește încărcarea reclamelor, videoclipurilor și a altor conținuturi externe care conțin coduri de urmărire. Poate afecta anumite funcționalități ale site-ului.</string>
|
||||
<!-- Enhanced Tracking Protection Onboarding Message shown in a dialog above the toolbar. The first parameter is the name of the application (For example: Fenix) -->
|
||||
<string name="etp_onboarding_cfr_message">Când scutul este violet, %s a blocat elemente de urmărire de pe un site. Atinge pentru mai multe informații.</string>
|
||||
<!-- Enhanced Tracking Protection message that protection is currently on for this site -->
|
||||
<string name="etp_panel_on">Protecțiile sunt ACTIVE pentru acest site</string>
|
||||
<!-- Enhanced Tracking Protection message that protection is currently off for this site -->
|
||||
|
@ -1069,6 +1146,8 @@
|
|||
|
||||
<!-- About page link text to open support link -->
|
||||
<string name="about_support">Asistență</string>
|
||||
<!-- About page link text to list of past crashes (like about:crashes on desktop) -->
|
||||
<string name="about_crashes">Defecțiuni</string>
|
||||
<!-- About page link text to open privacy notice link -->
|
||||
<string name="about_privacy_notice">Politică de confidențialitate</string>
|
||||
<!-- About page link text to open know your rights link -->
|
||||
|
@ -1204,6 +1283,13 @@
|
|||
<!-- Summary for Accessibility Force Enable Zoom Preference -->
|
||||
<string name="preference_accessibility_force_enable_zoom_summary">Activează permiterea apropierii/depărtării cu degetele pentru zoom, chiar și pe site-uri web care împiedică acest gest.</string>
|
||||
|
||||
<!-- Saved logins sorting strategy menu item -by name- (if selected, it will sort saved logins alphabetically) -->
|
||||
<string name="saved_logins_sort_strategy_alphabetically">Denumire (A-Z)</string>
|
||||
<!-- Saved logins sorting strategy menu item -by last used- (if selected, it will sort saved logins by last used) -->
|
||||
<string name="saved_logins_sort_strategy_last_used">Folosite ultima dată</string>
|
||||
<!-- Content description (not visible, for screen readers etc.): Sort saved logins dropdown menu chevron icon -->
|
||||
<string name="saved_logins_menu_dropdown_chevron_icon_content_description">Meniu de sortare a datelor de autentificare</string>
|
||||
|
||||
<!-- Title of the Add search engine screen -->
|
||||
<string name="search_engine_add_custom_search_engine_title">Adaugă un motor de căutare</string>
|
||||
<!-- Title of the Edit search engine screen -->
|
||||
|
@ -1296,11 +1382,57 @@
|
|||
<string name="certificate_info_verified_by">Verificat de: %1$s</string>
|
||||
<!-- Login overflow menu delete button -->
|
||||
<string name="login_menu_delete_button">Șterge</string>
|
||||
<!-- Login overflow menu edit button -->
|
||||
<string name="login_menu_edit_button">Editează</string>
|
||||
<!-- Message in delete confirmation dialog for logins -->
|
||||
<string name="login_deletion_confirmation">Sigur vrei să ștergi aceste date de autentificare?</string>
|
||||
<!-- Positive action of a dialog asking to delete -->
|
||||
<string name="dialog_delete_positive">Șterge</string>
|
||||
|
||||
<!-- The saved login options menu description. -->
|
||||
<string name="login_options_menu">Opțiuni de autentificare</string>
|
||||
<!-- The editable text field for a login's web address. -->
|
||||
<string name="saved_login_hostname_description">Câmpul de text editabil pentru adresa web a datelor de autentificare.</string>
|
||||
<!-- The editable text field for a login's username. -->
|
||||
<string name="saved_login_username_description">Câmpul de text editabil pentru numele de utilizator al datelor de autentificare.</string>
|
||||
<!-- The editable text field for a login's password. -->
|
||||
<string name="saved_login_password_description">Câmp de text editabil pentru parola datelor de autentificare.</string>
|
||||
<!-- The button description to save changes to an edited login. -->
|
||||
<string name="save_changes_to_login">Salvează modificările datelor de autentificare.</string>
|
||||
<!-- The button description to discard changes to an edited login. -->
|
||||
<string name="discard_changes">Renunță la modificări</string>
|
||||
<!-- The page title for editing a saved login. -->
|
||||
<string name="edit">Editează</string>
|
||||
<!-- The error message in edit login view when password field is blank. -->
|
||||
<string name="saved_login_password_required">Necesită o parolă</string>
|
||||
<!-- Voice search button content description -->
|
||||
<string name="voice_search_content_description">Căutare vocală</string>
|
||||
<!-- Voice search prompt description displayed after the user presses the voice search button -->
|
||||
<string name="voice_search_explainer">Vorbește acum</string>
|
||||
<!-- The error message in edit login view when a duplicate username exists. -->
|
||||
<string name="saved_login_duplicate">Există un set de date de autentificare cu acest nume de utilizator</string>
|
||||
|
||||
<!-- Synced Tabs -->
|
||||
<!-- Text displayed when user is not logged into a Firefox Account -->
|
||||
<string name="synced_tabs_connect_to_sync_account">Conectare cu un cont Firefox.</string>
|
||||
<!-- Text displayed to ask user to connect another device as no devices found with account -->
|
||||
<string name="synced_tabs_connect_another_device">Conectează alt dispozitiv.</string>
|
||||
<!-- Text displayed asking user to re-authenticate -->
|
||||
<string name="synced_tabs_reauth">Te rugăm să te autentifici din nou.</string>
|
||||
<!-- Text displayed when user has disabled tab syncing in Firefox Sync Account -->
|
||||
<string name="synced_tabs_enable_tab_syncing">Te rugăm să activezi sincronizarea filelor.</string>
|
||||
<!-- Text displayed when user has no tabs that have been synced -->
|
||||
<string name="synced_tabs_no_tabs">Nu ai nicio filă deschisă în Firefox pe celelalte dispozitive.</string>
|
||||
<!-- Text displayed in the synced tabs screen when a user is not signed in to Firefox Sync describing Synced Tabs -->
|
||||
<string name="synced_tabs_sign_in_message">Afișează o listă de file de pe celelalte dispozitive.</string>
|
||||
<!-- Text displayed on a button in the synced tabs screen to link users to sign in when a user is not signed in to Firefox Sync -->
|
||||
<string name="synced_tabs_sign_in_button">Autentifică-te în Sync</string>
|
||||
|
||||
<!-- Top Sites -->
|
||||
<!-- Title text displayed in the dialog when top sites limit is reached. -->
|
||||
<string name="top_sites_max_limit_title">A fost atinsă limita de site-uri de top</string>
|
||||
<!-- Content description text displayed in the dialog when top sites limit is reached. -->
|
||||
<string name="top_sites_max_limit_content">Pentru a adăuga un site de top nou, trebuie să elimini unul existent. Ține degetul pe denumirea site-ului pentru selectare și apoi atinge „Elimină”.</string>
|
||||
<!-- Confirmation dialog button text when top sites limit is reached. -->
|
||||
<string name="top_sites_max_limit_confirmation_button">Ok, am înțeles</string>
|
||||
|
||||
|
|
|
@ -84,6 +84,8 @@
|
|||
|
||||
<declare-styleable name="OnboardingRadioButton">
|
||||
<attr name="onboardingKey" format="reference" />
|
||||
<attr name="onboardingKeyTitle" format="reference" />
|
||||
<attr name="onboardingKeyDescription" format="reference" />
|
||||
</declare-styleable>
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
<dimen name="radio_button_padding_vertical">12dp</dimen>
|
||||
<dimen name="radio_button_preference_height">48dp</dimen>
|
||||
<dimen name="radio_button_preference_horizontal">16dp</dimen>
|
||||
<dimen name="radio_button_preference_drawable_padding">16dp</dimen>
|
||||
<dimen name="radio_button_preference_drawable_padding">24dp</dimen>
|
||||
<dimen name="radio_button_preference_vertical">12dp</dimen>
|
||||
<dimen name="phone_feature_label_recommended_text_size">14sp</dimen>
|
||||
<dimen name="site_permissions_exceptions_item_text_size">18sp</dimen>
|
||||
|
@ -42,9 +42,10 @@
|
|||
<dimen name="context_menu_height">48dp</dimen>
|
||||
<dimen name="context_menu_x_offset">8dp</dimen>
|
||||
<dimen name="tp_onboarding_width">256dp</dimen>
|
||||
<dimen name="tp_onboarding_triangle_height">16dp</dimen>
|
||||
<dimen name="tp_onboarding_triangle_width">16dp</dimen>
|
||||
<dimen name="tp_onboarding_triangle_margin_start">16dp</dimen>
|
||||
<!-- Dimensions for the CFR (Contextual Feature Recommendation) tooltip triangle. -->
|
||||
<dimen name="cfr_triangle_height">16dp</dimen>
|
||||
<dimen name="cfr_triangle_width">16dp</dimen>
|
||||
<dimen name="cfr_triangle_margin_edge">16dp</dimen>
|
||||
|
||||
<dimen name="tab_counter_box_width_height">24dp</dimen>
|
||||
|
||||
|
@ -155,6 +156,8 @@
|
|||
|
||||
<!-- Tabs Tray -->
|
||||
<dimen name="tab_tray_top_offset">40dp</dimen>
|
||||
<dimen name="tab_tray_thumbnail_width">92dp</dimen>
|
||||
<dimen name="tab_tray_thumbnail_height">69dp</dimen>
|
||||
|
||||
<!-- Saved Logins Fragment -->
|
||||
<dimen name="saved_logins_sort_menu_dropdown_chevron_icon_margin_start">10dp</dimen>
|
||||
|
|
|
@ -33,4 +33,7 @@
|
|||
<!-- Label for the secret settings preference -->
|
||||
<string name="preferences_debug_settings">Secret Settings</string>
|
||||
<string name="preferences_debug_settings_enable_tab_tray">Use New Tab Tray</string>
|
||||
|
||||
<!-- Content description (not visible, for screen readers etc.) used to announce [LinkTextView]. -->
|
||||
<string name="link_text_view_type_announcement" translatable="false">link</string>
|
||||
</resources>
|
||||
|
|
|
@ -1432,6 +1432,4 @@
|
|||
<string name="top_sites_max_limit_content">To add a new top site, remove one. Long press the site and select remove.</string>
|
||||
<!-- Confirmation dialog button text when top sites limit is reached. -->
|
||||
<string name="top_sites_max_limit_confirmation_button">OK, Got It</string>
|
||||
<!-- Content description (not visible, for screen readers etc.) used to announce [LinkTextView]. -->
|
||||
<string name="link_text_view_type_announcement">link</string>
|
||||
</resources>
|
||||
|
|
|
@ -6,6 +6,8 @@ package org.mozilla.fenix
|
|||
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import io.mockk.every
|
||||
import io.mockk.spyk
|
||||
import mozilla.components.support.test.robolectric.testContext
|
||||
import mozilla.components.support.utils.toSafeIntent
|
||||
import org.junit.Assert.assertEquals
|
||||
|
@ -13,6 +15,7 @@ import org.junit.Assert.assertFalse
|
|||
import org.junit.Assert.assertNotEquals
|
||||
import org.junit.Assert.assertNull
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mozilla.fenix.HomeActivity.Companion.PRIVATE_BROWSING_MODE
|
||||
|
@ -24,10 +27,17 @@ import org.mozilla.fenix.helpers.FenixRobolectricTestRunner
|
|||
@RunWith(FenixRobolectricTestRunner::class)
|
||||
class HomeActivityTest {
|
||||
|
||||
private lateinit var activity: HomeActivity
|
||||
|
||||
@Before
|
||||
fun setup() {
|
||||
activity = spyk(HomeActivity())
|
||||
|
||||
every { activity.applicationContext } returns testContext
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getIntentSource() {
|
||||
val activity = HomeActivity()
|
||||
|
||||
val launcherIntent = Intent(Intent.ACTION_MAIN).apply {
|
||||
addCategory(Intent.CATEGORY_LAUNCHER)
|
||||
}.toSafeIntent()
|
||||
|
@ -42,8 +52,6 @@ class HomeActivityTest {
|
|||
|
||||
@Test
|
||||
fun `getModeFromIntentOrLastKnown returns mode from settings when intent does not set`() {
|
||||
val activity = HomeActivity()
|
||||
|
||||
testContext.settings().lastKnownMode = BrowsingMode.Private
|
||||
|
||||
assertEquals(testContext.settings().lastKnownMode, activity.getModeFromIntentOrLastKnown(null))
|
||||
|
@ -51,8 +59,6 @@ class HomeActivityTest {
|
|||
|
||||
@Test
|
||||
fun `getModeFromIntentOrLastKnown returns mode from intent when set`() {
|
||||
val activity = HomeActivity()
|
||||
|
||||
testContext.settings().lastKnownMode = BrowsingMode.Normal
|
||||
|
||||
val intent = Intent()
|
||||
|
@ -64,21 +70,16 @@ class HomeActivityTest {
|
|||
|
||||
@Test
|
||||
fun `isActivityColdStarted returns true for null savedInstanceState and not launched from history`() {
|
||||
val activity = HomeActivity()
|
||||
|
||||
assertTrue(activity.isActivityColdStarted(Intent(), null))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `isActivityColdStarted returns false for valid savedInstanceState and not launched from history`() {
|
||||
val activity = HomeActivity()
|
||||
|
||||
assertFalse(activity.isActivityColdStarted(Intent(), Bundle()))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `isActivityColdStarted returns false for null savedInstanceState and launched from history`() {
|
||||
val activity = HomeActivity()
|
||||
val startingIntent = Intent().apply {
|
||||
flags = flags or Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY
|
||||
}
|
||||
|
@ -88,7 +89,6 @@ class HomeActivityTest {
|
|||
|
||||
@Test
|
||||
fun `isActivityColdStarted returns false for null savedInstanceState and not launched from history`() {
|
||||
val activity = HomeActivity()
|
||||
val startingIntent = Intent().apply {
|
||||
flags = flags or Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY
|
||||
}
|
||||
|
|
|
@ -5,14 +5,19 @@
|
|||
package org.mozilla.fenix.browser.browsingmode
|
||||
|
||||
import io.mockk.MockKAnnotations
|
||||
import io.mockk.Runs
|
||||
import io.mockk.every
|
||||
import io.mockk.impl.annotations.MockK
|
||||
import io.mockk.just
|
||||
import io.mockk.verify
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.mozilla.fenix.utils.Settings
|
||||
|
||||
class DefaultBrowsingModeManagerTest {
|
||||
|
||||
@MockK lateinit var settings: Settings
|
||||
@MockK(relaxed = true) lateinit var callback: (BrowsingMode) -> Unit
|
||||
lateinit var manager: BrowsingModeManager
|
||||
|
||||
|
@ -21,7 +26,9 @@ class DefaultBrowsingModeManagerTest {
|
|||
@Before
|
||||
fun before() {
|
||||
MockKAnnotations.init(this)
|
||||
manager = DefaultBrowsingModeManager(initMode, callback)
|
||||
|
||||
manager = DefaultBrowsingModeManager(initMode, settings, callback)
|
||||
every { settings.lastKnownMode = any() } just Runs
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -46,8 +53,10 @@ class DefaultBrowsingModeManagerTest {
|
|||
|
||||
manager.mode = BrowsingMode.Private
|
||||
assertEquals(BrowsingMode.Private, manager.mode)
|
||||
verify { settings.lastKnownMode = BrowsingMode.Private }
|
||||
|
||||
manager.mode = BrowsingMode.Normal
|
||||
assertEquals(BrowsingMode.Normal, manager.mode)
|
||||
verify { settings.lastKnownMode = BrowsingMode.Normal }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,43 +4,43 @@
|
|||
|
||||
package org.mozilla.fenix.components
|
||||
|
||||
import android.content.Context
|
||||
import io.mockk.MockKAnnotations
|
||||
import io.mockk.Runs
|
||||
import io.mockk.every
|
||||
import io.mockk.impl.annotations.MockK
|
||||
import io.mockk.just
|
||||
import io.mockk.mockk
|
||||
import io.mockk.verify
|
||||
import mozilla.components.concept.sync.AccountObserver
|
||||
import mozilla.components.concept.sync.AuthType
|
||||
import mozilla.components.concept.sync.OAuthAccount
|
||||
import mozilla.components.service.fxa.DeviceConfig
|
||||
import mozilla.components.service.fxa.ServerConfig
|
||||
import mozilla.components.service.fxa.SyncConfig
|
||||
import mozilla.components.service.fxa.manager.FxaAccountManager
|
||||
import mozilla.components.support.base.observer.ObserverRegistry
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.mozilla.fenix.components.metrics.Event
|
||||
import org.mozilla.fenix.components.metrics.MetricController
|
||||
import org.mozilla.fenix.utils.Settings
|
||||
|
||||
class BackgroundServicesTest {
|
||||
class TestableBackgroundServices(
|
||||
val context: Context
|
||||
) : BackgroundServices(context, mockk(), mockk(), mockk(), mockk(), mockk(), mockk()) {
|
||||
override fun makeAccountManager(
|
||||
context: Context,
|
||||
serverConfig: ServerConfig,
|
||||
deviceConfig: DeviceConfig,
|
||||
syncConfig: SyncConfig?
|
||||
) = mockk<FxaAccountManager>(relaxed = true)
|
||||
|
||||
@MockK private lateinit var metrics: MetricController
|
||||
@MockK private lateinit var settings: Settings
|
||||
|
||||
private lateinit var observer: TelemetryAccountObserver
|
||||
private lateinit var registry: ObserverRegistry<AccountObserver>
|
||||
|
||||
@Before
|
||||
fun setup() {
|
||||
MockKAnnotations.init(this)
|
||||
every { metrics.track(any()) } just Runs
|
||||
every { settings.fxaSignedIn = any() } just Runs
|
||||
|
||||
observer = TelemetryAccountObserver(mockk(relaxed = true), metrics)
|
||||
registry = ObserverRegistry<AccountObserver>().apply { register(observer) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `telemetry account observer`() {
|
||||
val metrics = mockk<MetricController>()
|
||||
every { metrics.track(any()) } just Runs
|
||||
val observer = TelemetryAccountObserver(mockk(relaxed = true), metrics)
|
||||
val registry = ObserverRegistry<AccountObserver>()
|
||||
registry.register(observer)
|
||||
val account = mockk<OAuthAccount>()
|
||||
|
||||
// Sign-in
|
||||
|
|
|
@ -7,6 +7,7 @@ package org.mozilla.fenix.components
|
|||
import android.content.Context
|
||||
import io.mockk.mockk
|
||||
import org.mozilla.fenix.utils.ClipboardHandler
|
||||
import org.mozilla.fenix.utils.Settings
|
||||
|
||||
class TestComponents(private val context: Context) : Components(context) {
|
||||
override val backgroundServices by lazy {
|
||||
|
@ -29,4 +30,6 @@ class TestComponents(private val context: Context) : Components(context) {
|
|||
override val analytics by lazy { Analytics(context) }
|
||||
|
||||
override val clipboardHandler by lazy { ClipboardHandler(context) }
|
||||
|
||||
override val settings by lazy { mockk<Settings>(relaxed = true) }
|
||||
}
|
||||
|
|
|
@ -543,7 +543,10 @@ class DefaultBrowserToolbarControllerTest {
|
|||
|
||||
@Test
|
||||
fun handleToolbarNewTabPress() = runBlockingTest {
|
||||
val browsingModeManager: BrowsingModeManager = DefaultBrowsingModeManager(BrowsingMode.Private) {}
|
||||
val browsingModeManager: BrowsingModeManager = DefaultBrowsingModeManager(
|
||||
BrowsingMode.Private,
|
||||
mockk(relaxed = true)
|
||||
) {}
|
||||
val item = TabCounterMenuItem.NewTab(false)
|
||||
|
||||
every { activity.browsingModeManager } returns browsingModeManager
|
||||
|
@ -556,7 +559,10 @@ class DefaultBrowserToolbarControllerTest {
|
|||
|
||||
@Test
|
||||
fun handleToolbarNewPrivateTabPress() = runBlockingTest {
|
||||
val browsingModeManager: BrowsingModeManager = DefaultBrowsingModeManager(BrowsingMode.Normal) {}
|
||||
val browsingModeManager: BrowsingModeManager = DefaultBrowsingModeManager(
|
||||
BrowsingMode.Normal,
|
||||
mockk(relaxed = true)
|
||||
) {}
|
||||
val item = TabCounterMenuItem.NewTab(true)
|
||||
|
||||
every { activity.browsingModeManager } returns browsingModeManager
|
||||
|
|
|
@ -7,15 +7,14 @@ package org.mozilla.fenix.home.sessioncontrol.viewholders.onboarding
|
|||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import io.mockk.every
|
||||
import io.mockk.mockk
|
||||
import kotlinx.android.synthetic.main.onboarding_toolbar_position_picker.view.*
|
||||
import mozilla.components.support.test.robolectric.testContext
|
||||
import org.junit.After
|
||||
import org.junit.Assert.assertFalse
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mozilla.fenix.ext.components
|
||||
import org.mozilla.fenix.helpers.FenixRobolectricTestRunner
|
||||
import org.mozilla.fenix.utils.Settings
|
||||
|
||||
|
@ -27,16 +26,10 @@ class OnboardingToolbarPositionPickerViewHolderTest {
|
|||
|
||||
@Before
|
||||
fun setup() {
|
||||
val components = testContext.components
|
||||
view = LayoutInflater.from(testContext)
|
||||
.inflate(OnboardingToolbarPositionPickerViewHolder.LAYOUT_ID, null)
|
||||
settings = mockk(relaxed = true)
|
||||
|
||||
Settings.instance = settings
|
||||
}
|
||||
|
||||
@After
|
||||
fun teardown() {
|
||||
Settings.instance = null
|
||||
settings = components.settings
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -0,0 +1,183 @@
|
|||
/* 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.push
|
||||
|
||||
import android.util.Base64
|
||||
import io.mockk.Called
|
||||
import io.mockk.CapturingSlot
|
||||
import io.mockk.MockKAnnotations
|
||||
import io.mockk.Runs
|
||||
import io.mockk.every
|
||||
import io.mockk.impl.annotations.MockK
|
||||
import io.mockk.just
|
||||
import io.mockk.mockk
|
||||
import io.mockk.mockkStatic
|
||||
import io.mockk.slot
|
||||
import io.mockk.unmockkStatic
|
||||
import io.mockk.verify
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.test.TestCoroutineScope
|
||||
import kotlinx.coroutines.test.runBlockingTest
|
||||
import mozilla.components.concept.engine.Engine
|
||||
import mozilla.components.concept.engine.webpush.WebPushDelegate
|
||||
import mozilla.components.concept.engine.webpush.WebPushHandler
|
||||
import mozilla.components.concept.engine.webpush.WebPushSubscription
|
||||
import mozilla.components.feature.push.AutoPushFeature
|
||||
import mozilla.components.feature.push.AutoPushSubscription
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
|
||||
@ExperimentalCoroutinesApi
|
||||
class WebPushEngineIntegrationTest {
|
||||
|
||||
private val scope = TestCoroutineScope()
|
||||
@MockK private lateinit var engine: Engine
|
||||
@MockK private lateinit var pushFeature: AutoPushFeature
|
||||
@MockK(relaxed = true) private lateinit var handler: WebPushHandler
|
||||
private lateinit var delegate: CapturingSlot<WebPushDelegate>
|
||||
private lateinit var integration: WebPushEngineIntegration
|
||||
|
||||
@Before
|
||||
fun setup() {
|
||||
MockKAnnotations.init(this)
|
||||
mockkStatic(Base64::class)
|
||||
delegate = slot()
|
||||
|
||||
every { engine.registerWebPushDelegate(capture(delegate)) } returns handler
|
||||
every { pushFeature.register(any()) } just Runs
|
||||
every { pushFeature.unregister(any()) } just Runs
|
||||
every { Base64.decode(any<ByteArray>(), any()) } answers { firstArg() }
|
||||
|
||||
integration = WebPushEngineIntegration(engine, pushFeature, scope)
|
||||
}
|
||||
|
||||
@After
|
||||
fun teardown() {
|
||||
unmockkStatic(Base64::class)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `methods are no-op before calling start`() = scope.runBlockingTest {
|
||||
integration.onMessageReceived("push", null)
|
||||
integration.onSubscriptionChanged("push")
|
||||
verify { handler wasNot Called }
|
||||
|
||||
integration.start()
|
||||
|
||||
integration.onMessageReceived("push", null)
|
||||
verify { handler.onPushMessage("push", null) }
|
||||
|
||||
integration.onSubscriptionChanged("push")
|
||||
verify { handler.onSubscriptionChanged("push") }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `start and stop register and unregister pushFeature`() {
|
||||
integration.start()
|
||||
verify { pushFeature.register(integration) }
|
||||
|
||||
integration.stop()
|
||||
verify { pushFeature.unregister(integration) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `delegate calls getSubscription`() {
|
||||
integration.start()
|
||||
val slot = slot<(AutoPushSubscription?) -> Unit>()
|
||||
every { pushFeature.getSubscription("scope", block = capture(slot)) } just Runs
|
||||
|
||||
val onSubscription = mockk<(WebPushSubscription?) -> Unit>(relaxed = true)
|
||||
delegate.captured.onGetSubscription("scope", onSubscription)
|
||||
|
||||
verify { onSubscription wasNot Called }
|
||||
slot.captured(AutoPushSubscription(
|
||||
scope = "scope",
|
||||
publicKey = "abc",
|
||||
endpoint = "def",
|
||||
authKey = "xyz",
|
||||
appServerKey = null
|
||||
))
|
||||
|
||||
verify {
|
||||
onSubscription(
|
||||
WebPushSubscription(
|
||||
scope = "scope",
|
||||
publicKey = "abc".toByteArray(),
|
||||
endpoint = "def",
|
||||
authSecret = "xyz".toByteArray(),
|
||||
appServerKey = null
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `delegate calls subscribe`() {
|
||||
integration.start()
|
||||
val onSubscribeError = slot<() -> Unit>()
|
||||
val onSubscribe = slot<(AutoPushSubscription?) -> Unit>()
|
||||
every {
|
||||
pushFeature.subscribe(
|
||||
scope = "scope",
|
||||
appServerKey = null,
|
||||
onSubscribeError = capture(onSubscribeError),
|
||||
onSubscribe = capture(onSubscribe)
|
||||
)
|
||||
} just Runs
|
||||
|
||||
val onSubscription = mockk<(WebPushSubscription?) -> Unit>(relaxed = true)
|
||||
delegate.captured.onSubscribe("scope", null, onSubscription)
|
||||
|
||||
verify { onSubscription wasNot Called }
|
||||
|
||||
onSubscribeError.captured()
|
||||
verify { onSubscription(null) }
|
||||
|
||||
onSubscribe.captured(AutoPushSubscription(
|
||||
scope = "scope",
|
||||
publicKey = "abc",
|
||||
endpoint = "def",
|
||||
authKey = "xyz",
|
||||
appServerKey = null
|
||||
))
|
||||
verify {
|
||||
onSubscription(
|
||||
WebPushSubscription(
|
||||
scope = "scope",
|
||||
publicKey = "abc".toByteArray(),
|
||||
endpoint = "def",
|
||||
authSecret = "xyz".toByteArray(),
|
||||
appServerKey = null
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `delegate calls unsubscribe`() {
|
||||
integration.start()
|
||||
val onUnsubscribeError = slot<() -> Unit>()
|
||||
val onUnsubscribe = slot<(Boolean) -> Unit>()
|
||||
every {
|
||||
pushFeature.unsubscribe(
|
||||
scope = "scope",
|
||||
onUnsubscribeError = capture(onUnsubscribeError),
|
||||
onUnsubscribe = capture(onUnsubscribe)
|
||||
)
|
||||
} just Runs
|
||||
|
||||
val onUnsubscription = mockk<(Boolean) -> Unit>(relaxed = true)
|
||||
delegate.captured.onUnsubscribe("scope", onUnsubscription)
|
||||
|
||||
verify { onUnsubscription wasNot Called }
|
||||
|
||||
onUnsubscribeError.captured()
|
||||
verify { onUnsubscription(false) }
|
||||
|
||||
onUnsubscribe.captured(true)
|
||||
verify { onUnsubscription(true) }
|
||||
}
|
||||
}
|
|
@ -35,7 +35,6 @@ import org.mozilla.fenix.ext.settings
|
|||
import org.mozilla.fenix.helpers.FenixRobolectricTestRunner
|
||||
import org.mozilla.fenix.settings.SupportUtils
|
||||
import org.mozilla.fenix.utils.Settings
|
||||
import org.mozilla.fenix.whatsnew.clear
|
||||
|
||||
@ExperimentalCoroutinesApi
|
||||
@RunWith(FenixRobolectricTestRunner::class)
|
||||
|
@ -48,10 +47,10 @@ class DefaultSearchControllerTest {
|
|||
private val searchEngine: SearchEngine = mockk(relaxed = true)
|
||||
private val metrics: MetricController = mockk(relaxed = true)
|
||||
private val sessionManager: SessionManager = mockk(relaxed = true)
|
||||
private val settings: Settings = mockk(relaxed = true)
|
||||
private val clearToolbarFocus: (() -> Unit) = mockk(relaxed = true)
|
||||
|
||||
private lateinit var controller: DefaultSearchController
|
||||
private lateinit var settings: Settings
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
|
@ -60,6 +59,7 @@ class DefaultSearchControllerTest {
|
|||
every { store.state.searchEngineSource.searchEngine } returns searchEngine
|
||||
every { activity.metrics } returns metrics
|
||||
every { activity.components.core.sessionManager } returns sessionManager
|
||||
every { activity.components.settings } returns settings
|
||||
|
||||
controller = DefaultSearchController(
|
||||
activity = activity,
|
||||
|
@ -67,8 +67,6 @@ class DefaultSearchControllerTest {
|
|||
navController = navController,
|
||||
clearToolbarFocus = clearToolbarFocus
|
||||
)
|
||||
|
||||
settings = testContext.settings().apply { testContext.settings().clear() }
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -154,10 +152,7 @@ class DefaultSearchControllerTest {
|
|||
@Test
|
||||
fun `show search shortcuts when setting enabled AND query empty`() {
|
||||
val text = ""
|
||||
testContext.settings().preferences
|
||||
.edit()
|
||||
.putBoolean(testContext.getString(R.string.pref_key_show_search_shortcuts), true)
|
||||
.apply()
|
||||
every { settings.shouldShowSearchShortcuts } returns true
|
||||
|
||||
controller.handleTextChanged(text)
|
||||
|
||||
|
@ -168,10 +163,7 @@ class DefaultSearchControllerTest {
|
|||
fun `show search shortcuts when setting enabled AND query equals url`() {
|
||||
val text = "mozilla.org"
|
||||
every { store.state.url } returns "mozilla.org"
|
||||
testContext.settings().preferences
|
||||
.edit()
|
||||
.putBoolean(testContext.getString(R.string.pref_key_show_search_shortcuts), true)
|
||||
.apply()
|
||||
every { settings.shouldShowSearchShortcuts } returns true
|
||||
|
||||
controller.handleTextChanged(text)
|
||||
|
||||
|
@ -189,10 +181,7 @@ class DefaultSearchControllerTest {
|
|||
|
||||
@Test
|
||||
fun `do not show search shortcuts when setting disabled AND query empty AND url not matching query`() {
|
||||
testContext.settings().preferences
|
||||
.edit()
|
||||
.putBoolean(testContext.getString(R.string.pref_key_show_search_shortcuts), false)
|
||||
.apply()
|
||||
every { settings.shouldShowSearchShortcuts } returns false
|
||||
|
||||
assertFalse(testContext.settings().shouldShowSearchShortcuts)
|
||||
|
||||
|
@ -205,10 +194,7 @@ class DefaultSearchControllerTest {
|
|||
|
||||
@Test
|
||||
fun `do not show search shortcuts when setting disabled AND query non-empty`() {
|
||||
testContext.settings().preferences
|
||||
.edit()
|
||||
.putBoolean(testContext.getString(R.string.pref_key_show_search_shortcuts), false)
|
||||
.apply()
|
||||
every { settings.shouldShowSearchShortcuts } returns false
|
||||
|
||||
assertFalse(testContext.settings().shouldShowSearchShortcuts)
|
||||
|
||||
|
|
|
@ -6,33 +6,58 @@ package org.mozilla.fenix.search.toolbar
|
|||
|
||||
import android.content.Context
|
||||
import androidx.appcompat.view.ContextThemeWrapper
|
||||
import androidx.core.graphics.drawable.toBitmap
|
||||
import io.mockk.MockKAnnotations
|
||||
import io.mockk.Runs
|
||||
import io.mockk.every
|
||||
import io.mockk.impl.annotations.MockK
|
||||
import io.mockk.just
|
||||
import io.mockk.mockk
|
||||
import io.mockk.slot
|
||||
import io.mockk.spyk
|
||||
import io.mockk.verify
|
||||
import mozilla.components.browser.toolbar.BrowserToolbar
|
||||
import mozilla.components.browser.toolbar.edit.EditToolbar
|
||||
import mozilla.components.concept.engine.Engine
|
||||
import mozilla.components.concept.toolbar.Toolbar
|
||||
import mozilla.components.support.test.robolectric.testContext
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertFalse
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.components.metrics.Event
|
||||
import org.mozilla.fenix.helpers.FenixRobolectricTestRunner
|
||||
import org.mozilla.fenix.search.SearchEngineSource
|
||||
import org.mozilla.fenix.search.SearchFragmentState
|
||||
|
||||
@RunWith(FenixRobolectricTestRunner::class)
|
||||
class ToolbarViewTest {
|
||||
|
||||
@MockK(relaxed = true) private lateinit var interactor: ToolbarInteractor
|
||||
@MockK private lateinit var engine: Engine
|
||||
private lateinit var context: Context
|
||||
private lateinit var toolbar: BrowserToolbar
|
||||
private val defaultState: SearchFragmentState = SearchFragmentState(
|
||||
tabId = null,
|
||||
url = "",
|
||||
searchTerms = "",
|
||||
query = "",
|
||||
searchEngineSource = SearchEngineSource.Default(mockk {
|
||||
every { name } returns "Search Engine"
|
||||
every { icon } returns testContext.getDrawable(R.drawable.ic_search)!!.toBitmap()
|
||||
}),
|
||||
defaultEngineSource = mockk(relaxed = true),
|
||||
showSearchSuggestionsHint = false,
|
||||
showSearchSuggestions = false,
|
||||
showSearchShortcuts = false,
|
||||
areShortcutsAvailable = true,
|
||||
showClipboardSuggestions = false,
|
||||
showHistorySuggestions = false,
|
||||
showBookmarkSuggestions = false,
|
||||
searchAccessPoint = Event.PerformedSearch.SearchAccessPoint.NONE
|
||||
)
|
||||
|
||||
@Before
|
||||
fun setup() {
|
||||
|
@ -72,6 +97,69 @@ class ToolbarViewTest {
|
|||
assertTrue(toolbar.private)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `View gets initialized only once`() {
|
||||
val view = buildToolbarView(false)
|
||||
assertFalse(view.isInitialized)
|
||||
|
||||
view.update(defaultState)
|
||||
view.update(defaultState)
|
||||
view.update(defaultState)
|
||||
|
||||
verify(exactly = 1) { toolbar.url = any() }
|
||||
verify(exactly = 1) { toolbar.setSearchTerms(any()) }
|
||||
verify(exactly = 1) { interactor.onTextChanged(any()) }
|
||||
// editMode gets called when the view is initialized. So it is called twice in this test
|
||||
verify(exactly = 2) { toolbar.editMode() }
|
||||
|
||||
assertTrue(view.isInitialized)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `URL gets set to the states query`() {
|
||||
val toolbarView = buildToolbarView(false)
|
||||
toolbarView.update(defaultState.copy(query = "Query"))
|
||||
|
||||
assertEquals("Query", toolbarView.view.url)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `URL gets set to the states pastedText if exists`() {
|
||||
val toolbarView = buildToolbarView(false)
|
||||
toolbarView.update(defaultState.copy(query = "Query", pastedText = "Pasted"))
|
||||
|
||||
assertEquals("Pasted", toolbarView.view.url)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `searchTerms get set if pastedText is null or empty`() {
|
||||
val toolbarView = buildToolbarView(false)
|
||||
toolbarView.update(defaultState.copy(query = "Query", pastedText = "", searchTerms = "Search Terms"))
|
||||
|
||||
verify { toolbar.setSearchTerms("Search Terms") }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `searchTerms don't get set if pastedText has a value`() {
|
||||
val toolbarView = buildToolbarView(false)
|
||||
toolbarView.update(
|
||||
defaultState.copy(query = "Query", pastedText = "PastedText", searchTerms = "Search Terms")
|
||||
)
|
||||
|
||||
verify(exactly = 0) { toolbar.setSearchTerms("Search Terms") }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `searchEngine name and icon get set on update`() {
|
||||
val editToolbar: EditToolbar = mockk(relaxed = true)
|
||||
every { toolbar.edit } returns editToolbar
|
||||
|
||||
val toolbarView = buildToolbarView(false)
|
||||
toolbarView.update(defaultState)
|
||||
|
||||
verify { editToolbar.setIcon(any(), "Search Engine") }
|
||||
}
|
||||
|
||||
private fun buildToolbarView(isPrivate: Boolean) = ToolbarView(
|
||||
context,
|
||||
interactor,
|
||||
|
|
|
@ -16,7 +16,6 @@ import kotlinx.coroutines.test.runBlockingTest
|
|||
import mozilla.components.browser.storage.sync.PlacesHistoryStorage
|
||||
import mozilla.components.concept.engine.Engine
|
||||
import mozilla.components.feature.tabs.TabsUseCases
|
||||
import mozilla.components.support.test.robolectric.testContext
|
||||
import mozilla.components.support.test.rule.MainCoroutineRule
|
||||
import org.junit.Before
|
||||
import org.junit.Ignore
|
||||
|
@ -26,7 +25,6 @@ import org.junit.runner.RunWith
|
|||
import org.mozilla.fenix.HomeActivity
|
||||
import org.mozilla.fenix.components.FenixSnackbar
|
||||
import org.mozilla.fenix.components.PermissionStorage
|
||||
import org.mozilla.fenix.ext.clearAndCommit
|
||||
import org.mozilla.fenix.ext.components
|
||||
import org.mozilla.fenix.helpers.FenixRobolectricTestRunner
|
||||
import org.mozilla.fenix.utils.Settings
|
||||
|
@ -38,8 +36,8 @@ class DeleteAndQuitTest {
|
|||
@get:Rule
|
||||
val coroutinesTestRule = MainCoroutineRule(TestCoroutineDispatcher())
|
||||
|
||||
private var activity: HomeActivity = mockk(relaxed = true)
|
||||
lateinit var settings: Settings
|
||||
private val activity: HomeActivity = mockk(relaxed = true)
|
||||
private val settings: Settings = mockk(relaxed = true)
|
||||
private val tabUseCases: TabsUseCases = mockk(relaxed = true)
|
||||
private val historyStorage: PlacesHistoryStorage = mockk(relaxed = true)
|
||||
private val permissionStorage: PermissionStorage = mockk(relaxed = true)
|
||||
|
@ -49,25 +47,18 @@ class DeleteAndQuitTest {
|
|||
|
||||
@Before
|
||||
fun setUp() {
|
||||
settings = Settings.getInstance(testContext).apply {
|
||||
clear()
|
||||
}
|
||||
|
||||
every { activity.components.core.historyStorage } returns historyStorage
|
||||
every { activity.components.core.permissionStorage } returns permissionStorage
|
||||
every { activity.components.useCases.tabsUseCases } returns tabUseCases
|
||||
every { tabUseCases.removeAllTabs } returns removeAllTabsUseCases
|
||||
every { activity.components.core.engine } returns engine
|
||||
}
|
||||
|
||||
private fun Settings.clear() {
|
||||
preferences.clearAndCommit()
|
||||
every { activity.components.settings } returns settings
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `delete only tabs and quit`() = runBlockingTest {
|
||||
// When
|
||||
settings.setDeleteDataOnQuit(DeleteBrowsingDataOnQuitType.TABS, true)
|
||||
every { settings.getDeleteDataOnQuit(DeleteBrowsingDataOnQuitType.TABS) } returns true
|
||||
|
||||
deleteAndQuit(activity, this, snackbar)
|
||||
|
||||
|
@ -97,7 +88,7 @@ class DeleteAndQuitTest {
|
|||
fun `delete everything and quit`() = runBlockingTest {
|
||||
// When
|
||||
DeleteBrowsingDataOnQuitType.values().forEach {
|
||||
settings.setDeleteDataOnQuit(it, true)
|
||||
every { settings.getDeleteDataOnQuit(it) } returns true
|
||||
}
|
||||
|
||||
deleteAndQuit(activity, this, snackbar)
|
||||
|
|
|
@ -6,7 +6,9 @@ package org.mozilla.fenix.trackingprotection
|
|||
|
||||
import android.content.Context
|
||||
import android.view.View
|
||||
import io.mockk.MockKAnnotations
|
||||
import io.mockk.every
|
||||
import io.mockk.impl.annotations.MockK
|
||||
import io.mockk.mockk
|
||||
import io.mockk.spyk
|
||||
import io.mockk.verify
|
||||
|
@ -16,28 +18,27 @@ import org.junit.Before
|
|||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.utils.Settings
|
||||
import org.mozilla.fenix.components.metrics.MetricController
|
||||
import org.mozilla.fenix.helpers.FenixRobolectricTestRunner
|
||||
import org.mozilla.fenix.utils.Settings
|
||||
|
||||
@RunWith(FenixRobolectricTestRunner::class)
|
||||
class TrackingProtectionOverlayTest {
|
||||
|
||||
private lateinit var context: Context
|
||||
private lateinit var settings: Settings
|
||||
private lateinit var toolbar: View
|
||||
private lateinit var icon: View
|
||||
private lateinit var session: Session
|
||||
private lateinit var overlay: TrackingProtectionOverlay
|
||||
@MockK(relaxed = true) private lateinit var settings: Settings
|
||||
@MockK(relaxed = true) private lateinit var metrics: MetricController
|
||||
@MockK(relaxed = true) private lateinit var toolbar: View
|
||||
@MockK(relaxed = true) private lateinit var icon: View
|
||||
@MockK(relaxed = true) private lateinit var session: Session
|
||||
@MockK(relaxed = true) private lateinit var overlay: TrackingProtectionOverlay
|
||||
|
||||
@Before
|
||||
fun setup() {
|
||||
MockKAnnotations.init(this)
|
||||
context = spyk(testContext)
|
||||
settings = mockk(relaxed = true)
|
||||
toolbar = mockk(relaxed = true)
|
||||
icon = mockk(relaxed = true)
|
||||
session = mockk(relaxed = true)
|
||||
|
||||
overlay = TrackingProtectionOverlay(context, settings) { toolbar }
|
||||
overlay = TrackingProtectionOverlay(context, settings, metrics) { toolbar }
|
||||
every { toolbar.findViewById<View>(R.id.mozac_browser_toolbar_tracking_protection_indicator) } returns icon
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
|
||||
package org.mozilla.fenix.utils
|
||||
|
||||
import org.mozilla.fenix.helpers.FenixRobolectricTestRunner
|
||||
import mozilla.components.feature.sitepermissions.SitePermissionsRules
|
||||
import mozilla.components.feature.sitepermissions.SitePermissionsRules.Action.ALLOWED
|
||||
import mozilla.components.feature.sitepermissions.SitePermissionsRules.Action.ASK_TO_ALLOW
|
||||
|
@ -17,8 +16,7 @@ import org.junit.Assert.assertTrue
|
|||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mozilla.fenix.ext.clearAndCommit
|
||||
import org.mozilla.fenix.ext.settings
|
||||
import org.mozilla.fenix.helpers.FenixRobolectricTestRunner
|
||||
import org.mozilla.fenix.settings.PhoneFeature
|
||||
import org.mozilla.fenix.settings.deletebrowsingdata.DeleteBrowsingDataOnQuitType
|
||||
|
||||
|
@ -27,9 +25,18 @@ class SettingsTest {
|
|||
|
||||
lateinit var settings: Settings
|
||||
|
||||
private val defaultPermissions = SitePermissionsRules(
|
||||
camera = ASK_TO_ALLOW,
|
||||
location = ASK_TO_ALLOW,
|
||||
microphone = ASK_TO_ALLOW,
|
||||
notification = ASK_TO_ALLOW,
|
||||
autoplayAudible = AutoplayAction.BLOCKED,
|
||||
autoplayInaudible = AutoplayAction.BLOCKED
|
||||
)
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
settings = testContext.settings().apply(Settings::clear)
|
||||
settings = Settings(testContext)
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -103,28 +110,6 @@ class SettingsTest {
|
|||
assertEquals("Mozilla", settings.defaultSearchEngineName)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun isCrashReportingEnabled_enabledInBuild() {
|
||||
// When
|
||||
clearExistingInstance()
|
||||
val settings = testContext.settings(true)
|
||||
.apply(Settings::clear)
|
||||
|
||||
// Then
|
||||
assertTrue(settings.isCrashReportingEnabled)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun isCrashReportingEnabled_disabledInBuild() {
|
||||
// When
|
||||
clearExistingInstance()
|
||||
val settings = testContext.settings(false)
|
||||
.apply(Settings::clear)
|
||||
|
||||
// Then
|
||||
assertFalse(settings.isCrashReportingEnabled)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun isRemoteDebuggingEnabled() {
|
||||
// When just created
|
||||
|
@ -451,7 +436,7 @@ class SettingsTest {
|
|||
// When just created
|
||||
// Then
|
||||
assertEquals(
|
||||
defaultPermissions(),
|
||||
defaultPermissions,
|
||||
settings.getSitePermissionsCustomSettingsRules()
|
||||
)
|
||||
}
|
||||
|
@ -463,7 +448,7 @@ class SettingsTest {
|
|||
|
||||
// Then
|
||||
assertEquals(
|
||||
defaultPermissions().copy(camera = BLOCKED),
|
||||
defaultPermissions.copy(camera = BLOCKED),
|
||||
settings.getSitePermissionsCustomSettingsRules()
|
||||
)
|
||||
}
|
||||
|
@ -475,7 +460,7 @@ class SettingsTest {
|
|||
|
||||
// Then
|
||||
assertEquals(
|
||||
defaultPermissions().copy(notification = BLOCKED),
|
||||
defaultPermissions.copy(notification = BLOCKED),
|
||||
settings.getSitePermissionsCustomSettingsRules()
|
||||
)
|
||||
}
|
||||
|
@ -487,7 +472,7 @@ class SettingsTest {
|
|||
|
||||
// Then
|
||||
assertEquals(
|
||||
defaultPermissions().copy(location = BLOCKED),
|
||||
defaultPermissions.copy(location = BLOCKED),
|
||||
settings.getSitePermissionsCustomSettingsRules()
|
||||
)
|
||||
}
|
||||
|
@ -499,7 +484,7 @@ class SettingsTest {
|
|||
|
||||
// Then
|
||||
assertEquals(
|
||||
defaultPermissions().copy(microphone = BLOCKED),
|
||||
defaultPermissions.copy(microphone = BLOCKED),
|
||||
settings.getSitePermissionsCustomSettingsRules()
|
||||
)
|
||||
}
|
||||
|
@ -509,7 +494,7 @@ class SettingsTest {
|
|||
settings.setSitePermissionsPhoneFeatureAction(PhoneFeature.AUTOPLAY_AUDIBLE, ALLOWED)
|
||||
|
||||
assertEquals(
|
||||
defaultPermissions().copy(autoplayAudible = ALLOWED),
|
||||
defaultPermissions.copy(autoplayAudible = ALLOWED),
|
||||
settings.getSitePermissionsCustomSettingsRules()
|
||||
)
|
||||
}
|
||||
|
@ -519,25 +504,8 @@ class SettingsTest {
|
|||
settings.setSitePermissionsPhoneFeatureAction(PhoneFeature.AUTOPLAY_INAUDIBLE, ALLOWED)
|
||||
|
||||
assertEquals(
|
||||
defaultPermissions().copy(autoplayInaudible = ALLOWED),
|
||||
defaultPermissions.copy(autoplayInaudible = ALLOWED),
|
||||
settings.getSitePermissionsCustomSettingsRules()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun clearExistingInstance() {
|
||||
Settings.instance = null
|
||||
}
|
||||
|
||||
private fun Settings.clear() {
|
||||
preferences.clearAndCommit()
|
||||
}
|
||||
|
||||
private fun defaultPermissions() = SitePermissionsRules(
|
||||
camera = ASK_TO_ALLOW,
|
||||
location = ASK_TO_ALLOW,
|
||||
microphone = ASK_TO_ALLOW,
|
||||
notification = ASK_TO_ALLOW,
|
||||
autoplayAudible = AutoplayAction.BLOCKED,
|
||||
autoplayInaudible = AutoplayAction.BLOCKED
|
||||
)
|
||||
|
|
|
@ -4,25 +4,24 @@
|
|||
|
||||
package org.mozilla.fenix.whatsnew
|
||||
|
||||
import org.mozilla.fenix.helpers.FenixRobolectricTestRunner
|
||||
import androidx.preference.PreferenceManager
|
||||
import mozilla.components.support.test.robolectric.testContext
|
||||
import org.junit.Assert
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mozilla.fenix.ext.clearAndCommit
|
||||
import org.mozilla.fenix.utils.Settings
|
||||
import org.mozilla.fenix.helpers.FenixRobolectricTestRunner
|
||||
|
||||
@RunWith(FenixRobolectricTestRunner::class)
|
||||
class WhatsNewStorageTest {
|
||||
|
||||
private lateinit var storage: SharedPreferenceWhatsNewStorage
|
||||
private lateinit var settings: Settings
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
storage = SharedPreferenceWhatsNewStorage(testContext)
|
||||
settings = Settings.getInstance(testContext)
|
||||
.apply(Settings::clear)
|
||||
PreferenceManager.getDefaultSharedPreferences(testContext).clearAndCommit()
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -57,7 +56,3 @@ class WhatsNewStorageTest {
|
|||
const val DAY_IN_MILLIS = 3600 * 1000 * 24
|
||||
}
|
||||
}
|
||||
|
||||
fun Settings.clear() {
|
||||
preferences.clearAndCommit()
|
||||
}
|
||||
|
|
|
@ -4,24 +4,24 @@ package org.mozilla.fenix.whatsnew
|
|||
* 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/. */
|
||||
|
||||
import org.mozilla.fenix.helpers.FenixRobolectricTestRunner
|
||||
import androidx.preference.PreferenceManager
|
||||
import mozilla.components.support.test.robolectric.testContext
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mozilla.fenix.ext.settings
|
||||
import org.mozilla.fenix.utils.Settings
|
||||
import org.mozilla.fenix.ext.clearAndCommit
|
||||
import org.mozilla.fenix.helpers.FenixRobolectricTestRunner
|
||||
|
||||
@RunWith(FenixRobolectricTestRunner::class)
|
||||
class WhatsNewTest {
|
||||
|
||||
private lateinit var storage: SharedPreferenceWhatsNewStorage
|
||||
private lateinit var settings: Settings
|
||||
|
||||
@Before
|
||||
fun setup() {
|
||||
storage = SharedPreferenceWhatsNewStorage(testContext)
|
||||
settings = testContext.settings().apply(Settings::clear)
|
||||
PreferenceManager.getDefaultSharedPreferences(testContext).clearAndCommit()
|
||||
WhatsNew.wasUpdatedRecently = null
|
||||
}
|
||||
|
||||
|
|
|
@ -18,11 +18,11 @@ def trim_to_locale(str):
|
|||
return match.group(1)
|
||||
|
||||
|
||||
# This file is a dumb parser that converts values from '/l10n.toml' to be easily consumed from
|
||||
# Python.
|
||||
# This file is a dumb parser that converts values from '/l10n-release.toml' to be easily
|
||||
# consumed from Python.
|
||||
#
|
||||
# 'l10n.toml' has a very simple structure, and it is reasonable to believe that this (very basic)
|
||||
# algorithm will continue to work as it is changed.
|
||||
# 'l10n-release.toml' has a very simple structure, and it is reasonable to believe that this
|
||||
# (very basic) algorithm will continue to work as it is changed.
|
||||
#
|
||||
# Alternatives to custom parsing that were considered:
|
||||
# - Using standard library module --- none exists to parse TOML
|
||||
|
@ -31,7 +31,7 @@ def trim_to_locale(str):
|
|||
# - Vendoring a TOML module --- large amount of code given the use case. Introduces a security
|
||||
# risk
|
||||
def get_release_locales():
|
||||
with open(r"l10n.toml") as f:
|
||||
with open(r"l10n-release.toml") as f:
|
||||
file = f.read().splitlines()
|
||||
|
||||
locales_opened = False
|
||||
|
|
|
@ -72,7 +72,7 @@ buildscript {
|
|||
}
|
||||
|
||||
plugins {
|
||||
id("io.gitlab.arturbosch.detekt").version("1.6.0")
|
||||
id("io.gitlab.arturbosch.detekt").version("1.9.1")
|
||||
}
|
||||
|
||||
allprojects {
|
||||
|
@ -133,8 +133,7 @@ allprojects {
|
|||
kotlinOptions.jvmTarget = "1.8"
|
||||
kotlinOptions.allWarningsAsErrors = true
|
||||
kotlinOptions.freeCompilerArgs += [
|
||||
"-Xuse-experimental=kotlin.Experimental",
|
||||
"-Xskip-runtime-version-check"
|
||||
"-Xuse-experimental=kotlin.Experimental"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
@ -145,9 +144,10 @@ task clean(type: Delete) {
|
|||
|
||||
detekt {
|
||||
// The version number is duplicated, please refer to plugins block for more details
|
||||
version = "1.6.0"
|
||||
version = "1.9.1"
|
||||
input = files("$projectDir/app/src")
|
||||
config = files("$projectDir/config/detekt.yml")
|
||||
baseline = file("$projectDir/config/detekt-baseline.xml")
|
||||
|
||||
reports {
|
||||
html {
|
||||
|
|
|
@ -3,5 +3,5 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
object AndroidComponents {
|
||||
const val VERSION = "51.0.20200720130437"
|
||||
const val VERSION = "51.0.20200721130108"
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ object Versions {
|
|||
const val leanplum = "5.4.0"
|
||||
const val osslicenses_plugin = "0.9.5"
|
||||
const val osslicenses_library = "17.0.0"
|
||||
const val detekt = "1.6.0"
|
||||
const val detekt = "1.9.1"
|
||||
|
||||
const val androidx_appcompat = "1.2.0-rc01"
|
||||
const val androidx_biometric = "1.1.0-alpha01"
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -23,10 +23,6 @@ console-reports:
|
|||
# - 'NotificationReport'
|
||||
# - 'FindingsReport'
|
||||
# - 'BuildFailureReport'
|
||||
|
||||
console-reports:
|
||||
active: true
|
||||
exclude:
|
||||
# - 'HtmlOutputReport'
|
||||
- 'PlainOutputReport'
|
||||
- 'XmlOutputReport'
|
||||
|
@ -34,6 +30,8 @@ console-reports:
|
|||
comments:
|
||||
active: true
|
||||
excludes: "**/*Test.kt, **/*Spec.kt, **/test/**, **/androidTest/**"
|
||||
AbsentOrWrongFileLicense:
|
||||
active: true
|
||||
CommentOverPrivateFunction:
|
||||
active: false
|
||||
CommentOverPrivateProperty:
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
/* 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/. */
|
|
@ -1,36 +0,0 @@
|
|||
# The `activation` ping
|
||||
|
||||
## Description
|
||||
This ping provides a measure of the activation of mobile products.
|
||||
|
||||
## Scheduling
|
||||
The `activation` ping is automatically sent at the very first startup, after Glean is initialized.
|
||||
It is only sent once and only re-attempted a subsequent startups if it hasn't been sent yet.
|
||||
|
||||
## Contents
|
||||
This ping contains the following fields:
|
||||
|
||||
| Field name | Type | Description |
|
||||
|---|---|---|
|
||||
| `identifier` | String | An hashed and salted version of the Google Advertising ID from the device. |
|
||||
| `activation_id` | UUID | An alternate identifier, not correlated with the client_id, generated once and only sent with the activation ping. |
|
||||
|
||||
The `activation` ping also includes the common [ping sections](https://github.com/mozilla-mobile/android-components/blob/master/components/service/glean/docs/pings/pings.md#ping-sections)
|
||||
found in all pings, with the exclusion of the `client_id` (as defined by the [`pings.yaml`](../app/pings.yaml) file).
|
||||
|
||||
## Example `activation` ping
|
||||
|
||||
```json
|
||||
{
|
||||
"ping_info": { },
|
||||
"client_info": { },
|
||||
"metrics": {
|
||||
"string": {
|
||||
"activation.identifier": "d+lnddDYN2ILBDGvhBIBHORRMrmVwTCp6rGLLFi8SMo="
|
||||
},
|
||||
"uuid": {
|
||||
"activation.activation_id": "c0c40a5f-bd75-41ca-8097-9a38103de7fe"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
|
@ -2,21 +2,10 @@
|
|||
|
||||
Fenix uses Mozilla's telemetry service (Glean) and LeanPlum to measure feature performance and engagement.
|
||||
|
||||
## Baseline ping
|
||||
## Glean pings and metrics
|
||||
By using the Glean SDK, Fenix can send the pings the SDK owns and defines, as documented [in the Glean SDK docs](https://mozilla.github.io/glean/book/user/pings/index.html).
|
||||
|
||||
Fenix creates and tries to send a "baseline" ping when the app goes to the background. This baseline ping is defined by the [Glean](https://github.com/mozilla/glean/tree/master/docs/user/pings) component and [documented in the Android Components repository](https://github.com/mozilla/glean/blob/master/docs/user/pings/baseline.md).
|
||||
|
||||
## Metrics ping
|
||||
|
||||
Fenix creates and tries to send a "baseline" ping. It is defined inside the [`metrics.yaml`](https://github.com/mozilla-mobile/fenix/blob/master/app/metrics.yaml) file. This ping includes things like whether or not Fenix is currently the default browser.
|
||||
|
||||
## Events
|
||||
|
||||
Fenix sends event pings that allows us to measure feature performance. These are defined inside the [`metrics.yaml`](https://github.com/mozilla-mobile/fenix/blob/master/app/metrics.yaml) file.
|
||||
|
||||
## Activation
|
||||
|
||||
Fenix sends an activation ping once, at startup. Further documentation can be found in the [`activation` ping](activation.md) docs.
|
||||
Additional metrics or pings defined by Fenix are documented in the [Glean SDK autogenerated docs](metrics.md).
|
||||
|
||||
## Leanplum
|
||||
See [here](https://github.com/mozilla-mobile/fenix/blob/master/docs/mma.md) for details on Leanplum usage in Firefox Preview.
|
||||
|
|
|
@ -0,0 +1,91 @@
|
|||
# Locales that should be present in release builds
|
||||
# Locales that are at 70% or higher completion on https://pontoon.mozilla.org/projects/android-l10n/
|
||||
# should be in this list
|
||||
locales = [
|
||||
"an",
|
||||
"ar",
|
||||
"ast",
|
||||
"az",
|
||||
"be",
|
||||
"bn",
|
||||
"br",
|
||||
"bs",
|
||||
"ca",
|
||||
"cak",
|
||||
"co",
|
||||
"cs",
|
||||
"cy",
|
||||
"da",
|
||||
"de",
|
||||
"dsb",
|
||||
"el",
|
||||
"en-CA",
|
||||
"en-GB",
|
||||
"eo",
|
||||
"es",
|
||||
"es-AR",
|
||||
"es-CL",
|
||||
"es-ES",
|
||||
"es-MX",
|
||||
"et",
|
||||
"eu",
|
||||
"fa",
|
||||
"ff",
|
||||
"fi",
|
||||
"fr",
|
||||
"fy-NL",
|
||||
"ga-IE",
|
||||
"gd",
|
||||
"gn",
|
||||
"gu-IN",
|
||||
"he",
|
||||
"hi-IN",
|
||||
"hr",
|
||||
"hsb",
|
||||
"hu",
|
||||
"hy-AM",
|
||||
"id",
|
||||
"is",
|
||||
"it",
|
||||
"ja",
|
||||
"ka",
|
||||
"kab",
|
||||
"kk",
|
||||
"kn",
|
||||
"ko",
|
||||
"lij",
|
||||
"lo",
|
||||
"lt",
|
||||
"ml",
|
||||
"mr",
|
||||
"my",
|
||||
"nb-NO",
|
||||
"nl",
|
||||
"nn-NO",
|
||||
"oc",
|
||||
"pa-IN",
|
||||
"pl",
|
||||
"pt-BR",
|
||||
"pt-PT",
|
||||
"rm",
|
||||
"ro",
|
||||
"ru",
|
||||
"sk",
|
||||
"sl",
|
||||
"sq",
|
||||
"sr",
|
||||
"su",
|
||||
"sv-SE",
|
||||
"ta",
|
||||
"te",
|
||||
"th",
|
||||
"tr",
|
||||
"trs",
|
||||
"uk",
|
||||
"ur",
|
||||
"vec",
|
||||
"vi",
|
||||
"zh-CN",
|
||||
"zh-TW",
|
||||
]
|
||||
|
|
@ -7,6 +7,7 @@ locales = [
|
|||
"ast",
|
||||
"az",
|
||||
"be",
|
||||
"bg",
|
||||
"bn",
|
||||
"br",
|
||||
"bs",
|
||||
|
@ -58,10 +59,13 @@ locales = [
|
|||
"lt",
|
||||
"ml",
|
||||
"mr",
|
||||
"ms",
|
||||
"my",
|
||||
"nb-NO",
|
||||
"ne-NP",
|
||||
"nl",
|
||||
"nn-NO",
|
||||
"nv",
|
||||
"oc",
|
||||
"pa-IN",
|
||||
"pl",
|
||||
|
@ -83,6 +87,7 @@ locales = [
|
|||
"trs",
|
||||
"uk",
|
||||
"ur",
|
||||
"uz",
|
||||
"vec",
|
||||
"vi",
|
||||
"zh-CN",
|
||||
|
|
|
@ -45,22 +45,14 @@ if (localProperties != null) {
|
|||
|
||||
if (appServicesLocalPath != null) {
|
||||
log("Enabling automatic publication of application-services from: $appServicesLocalPath")
|
||||
def publishAppServicesCmd = ["./automation/publish_to_maven_local_if_modified.py"]
|
||||
// Application-services doesn't build on native Windows. However, it still makes sense to
|
||||
// enable these workflows on Windows, even if it isn't quote as automatic as elsewhere -
|
||||
// specifically, you must run the build command on WSL, but after that you can happily build
|
||||
// and debug directly from within Android Studio on native Windows - but only after following
|
||||
// https://github.com/mozilla/application-services/blob/master/docs/howtos/setup-android-build-environment.md#using-windows
|
||||
// So rather than fail we make noise...
|
||||
// Windows can't execute .py files directly, so we assume a "manually installed" python,
|
||||
// which comes with a "py" launcher and respects the shebang line to specify the version.
|
||||
def publishAppServicesCmd = [];
|
||||
if (System.properties['os.name'].toLowerCase().contains('windows')) {
|
||||
log('NOTE: The autoPublish workflows do not work on native windows.');
|
||||
log('You must manually ensure that the following command has completed successfully in WSL:');
|
||||
log("> $publishAppServicesCmd");
|
||||
log("(from the '$appServicesLocalPath' directory)");
|
||||
log('Then restart the build');
|
||||
} else {
|
||||
runCmd(publishAppServicesCmd, appServicesLocalPath, "Published application-services for local development.", false)
|
||||
publishAppServicesCmd << "py";
|
||||
}
|
||||
publishAppServicesCmd << "./automation/publish_to_maven_local_if_modified.py";
|
||||
runCmd(publishAppServicesCmd, appServicesLocalPath, "Published application-services for local development.", false)
|
||||
} else {
|
||||
log("Disabled auto-publication of application-services. Enable it by settings '$settingAppServicesPath' in local.properties")
|
||||
}
|
||||
|
@ -68,10 +60,8 @@ if (localProperties != null) {
|
|||
String androidComponentsLocalPath = localProperties.getProperty(settingAndroidComponentsPath)
|
||||
|
||||
if (androidComponentsLocalPath != null) {
|
||||
// android-components does build on native windows, so it doesn't get the special Windows treatment above.
|
||||
// But it doesn't like executing .py files directly. We assume a "manually installed" python,
|
||||
// which comes with a "py" launcher and respects the shebang line to specify the version.
|
||||
log("Enabling automatic publication of android-components from: $androidComponentsLocalPath")
|
||||
// As above, hacks to execute .py files on Windows.
|
||||
def publishAcCmd = [];
|
||||
if (System.properties['os.name'].toLowerCase().contains('windows')) {
|
||||
publishAcCmd << "py";
|
||||
|
|
|
@ -82,7 +82,7 @@ job-defaults:
|
|||
- '--app=fenix'
|
||||
- '--browsertime'
|
||||
- '--cold'
|
||||
- '--binary=org.mozilla.fenix.nightly'
|
||||
- '--binary=org.mozilla.fenix'
|
||||
- '--activity=org.mozilla.fenix.IntentReceiverActivity'
|
||||
- '--download-symbols=ondemand'
|
||||
- '--browsertime-node=$MOZ_FETCHES_DIR/node/bin/node'
|
||||
|
@ -232,3 +232,15 @@ jobs:
|
|||
test-name: google-search-restaurants
|
||||
treeherder:
|
||||
symbol: 'Btime(tp6m-28-c)'
|
||||
|
||||
youtube-playback:
|
||||
test-name: youtube-playback
|
||||
run-visual-metrics: False
|
||||
treeherder:
|
||||
symbol: 'Btime(ytp)'
|
||||
args:
|
||||
by-abi:
|
||||
# Bug 1558456 - Stop tracking youtube-playback-test on motoG5 for >1080p cases
|
||||
armeabi-v7a:
|
||||
- '--test-url-params=exclude=1,2,9,10,17,18,21,22,26,28,30,32,39,40,47,48,55,56,63,64,71,72,79,80,83,84,89,90,95,96'
|
||||
default: []
|
||||
|
|
|
@ -93,17 +93,6 @@ jobs:
|
|||
treeherder:
|
||||
symbol: forPerformanceTest(B)
|
||||
|
||||
nightly:
|
||||
attributes:
|
||||
nightly: true
|
||||
include-nightly-version: true
|
||||
include-shippable-secrets: true
|
||||
run:
|
||||
geckoview-engine: geckoNightly
|
||||
gradle-build-type: fenixNightly
|
||||
treeherder:
|
||||
symbol: nightly(B)
|
||||
|
||||
nightly-simulation:
|
||||
attributes:
|
||||
nightly: false
|
||||
|
@ -112,47 +101,22 @@ jobs:
|
|||
include-shippable-secrets: true
|
||||
run:
|
||||
geckoview-engine: geckoNightly
|
||||
gradle-build-type: fennecNightly
|
||||
gradle-build-type: fenixProduction
|
||||
treeherder:
|
||||
symbol: nightlySim(B)
|
||||
|
||||
beta:
|
||||
attributes:
|
||||
release-type: beta
|
||||
include-release-version: true
|
||||
include-shippable-secrets: true
|
||||
filter-incomplete-translations: true
|
||||
run:
|
||||
geckoview-engine: geckoBeta
|
||||
gradle-build-type: fenixBeta
|
||||
run-on-tasks-for: [github-release]
|
||||
treeherder:
|
||||
symbol: beta(B)
|
||||
|
||||
# XXX `production` is now the new nightly. We keep this name around while we officially remove
|
||||
# `nightly` and `fennec-nightly`
|
||||
production:
|
||||
nightly:
|
||||
attributes:
|
||||
nightly: true
|
||||
include-nightly-version: true
|
||||
include-shippable-secrets: true
|
||||
run:
|
||||
geckoview-engine: geckoNightly
|
||||
# XXX `fenixProduction` is now the new nightly.
|
||||
gradle-build-type: fenixProduction
|
||||
run-on-tasks-for: [github-release]
|
||||
run-on-tasks-for: []
|
||||
treeherder:
|
||||
symbol: production(B)
|
||||
|
||||
fennec-nightly:
|
||||
attributes:
|
||||
nightly: true
|
||||
include-nightly-version: true
|
||||
include-shippable-secrets: true
|
||||
run:
|
||||
geckoview-engine: geckoNightly
|
||||
gradle-build-type: fennecNightly
|
||||
treeherder:
|
||||
symbol: nightlyFennec(B)
|
||||
symbol: nightly(B)
|
||||
|
||||
fennec-beta:
|
||||
attributes:
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
trust-domain: mobile
|
||||
treeherder:
|
||||
group-names:
|
||||
'beta': 'Beta-related tasks'
|
||||
'betaFennec': 'Beta-related tasks with same APK configuration as Fennec'
|
||||
'Btime': 'Raptor-Browsertime tests'
|
||||
'bump': 'Bump dependencies'
|
||||
|
@ -12,7 +11,6 @@ treeherder:
|
|||
'I': 'Docker Image Builds'
|
||||
'nightly': 'Nightly-related tasks'
|
||||
'nightlySim': 'Nightly-related tasks that run on each github push'
|
||||
'nightlyFennec': 'Nightly-related tasks with same APK configuration as Fennec'
|
||||
'production': 'Release-related tasks'
|
||||
'productionFennec': 'Production-related tasks with same APK configuration as Fennec'
|
||||
'Rap': 'Raptor tests'
|
||||
|
|
|
@ -17,8 +17,8 @@ primary-dependency: push-apk
|
|||
group-by: build-type
|
||||
|
||||
only-for-build-types:
|
||||
- fenix-beta
|
||||
- fenix-production
|
||||
- fennec-beta
|
||||
- fennec-production
|
||||
|
||||
job-template:
|
||||
description: Mark Fenix as shipped in ship-it
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue