diff --git a/app/build.gradle b/app/build.gradle index a13261c0b..c4f7f30b1 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -111,7 +111,7 @@ android.applicationVariants.all { variant -> // Set up kotlin-allopen plugin for writing tests // ------------------------------------------------------------------------------------------------- - boolean hasTest = gradle.startParameter.taskNames.find {it.contains("test") || it.contains("Test")} != null + boolean hasTest = gradle.startParameter.taskNames.find { it.contains("test") || it.contains("Test") } != null if (hasTest) { apply plugin: 'kotlin-allopen' allOpen { diff --git a/app/src/main/java/org/mozilla/fenix/AppRequestInterceptor.kt b/app/src/main/java/org/mozilla/fenix/AppRequestInterceptor.kt index 63d3655dd..35c3a903c 100644 --- a/app/src/main/java/org/mozilla/fenix/AppRequestInterceptor.kt +++ b/app/src/main/java/org/mozilla/fenix/AppRequestInterceptor.kt @@ -9,25 +9,8 @@ import mozilla.components.browser.errorpages.ErrorPages import mozilla.components.browser.errorpages.ErrorType import mozilla.components.concept.engine.EngineSession import mozilla.components.concept.engine.request.RequestInterceptor -import org.mozilla.fenix.ext.components -import org.mozilla.fenix.settings.AboutPage -import org.mozilla.fenix.settings.SettingsFragment class AppRequestInterceptor(private val context: Context) : RequestInterceptor { - override fun onLoadRequest( - session: EngineSession, - uri: String - ): RequestInterceptor.InterceptionResponse? { - return when (uri) { - SettingsFragment.aboutURL -> { - val page = AboutPage.createAboutPage(context) - return RequestInterceptor.InterceptionResponse.Content(page, encoding = base64) - } - - else -> context.components.services.accountsAuthFeature.interceptor.onLoadRequest(session, uri) - } - } - override fun onErrorRequest( session: EngineSession, errorType: ErrorType, @@ -35,8 +18,4 @@ class AppRequestInterceptor(private val context: Context) : RequestInterceptor { ): RequestInterceptor.ErrorResponse? { return RequestInterceptor.ErrorResponse(ErrorPages.createErrorPage(context, errorType)) } - - companion object { - const val base64 = "base64" - } } diff --git a/app/src/main/java/org/mozilla/fenix/settings/AboutFragment.kt b/app/src/main/java/org/mozilla/fenix/settings/AboutFragment.kt new file mode 100644 index 000000000..39e3a745e --- /dev/null +++ b/app/src/main/java/org/mozilla/fenix/settings/AboutFragment.kt @@ -0,0 +1,49 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package org.mozilla.fenix.settings + +import android.content.pm.PackageManager +import android.os.Bundle +import androidx.fragment.app.Fragment +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.appcompat.app.AppCompatActivity +import kotlinx.android.synthetic.main.fragment_about.* +import org.mozilla.fenix.R +import org.mozilla.geckoview.BuildConfig + +class AboutFragment : Fragment() { + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { + return inflater.inflate(R.layout.fragment_about, container, false) + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + val appName = requireContext().resources.getString(R.string.app_name) + (activity as AppCompatActivity).title = getString(R.string.preferences_about, appName) + + val aboutText = try { + val packageInfo = requireContext().packageManager.getPackageInfo(requireContext().packageName, 0) + val geckoVersion = packageInfo.versionCode.toString() + " \uD83E\uDD8E " + + BuildConfig.MOZ_APP_VERSION + "-" + BuildConfig.MOZ_APP_BUILDID + String.format( + "%s (Build #%s)", + packageInfo.versionName, + geckoVersion + ) + } catch (e: PackageManager.NameNotFoundException) { + "" + } + + val buildDate = org.mozilla.fenix.BuildConfig.BUILD_DATE + val content = resources.getString(R.string.about_content, appName) + + about_text.text = aboutText + about_content.text = content + build_date.text = buildDate + } +} diff --git a/app/src/main/java/org/mozilla/fenix/settings/AboutPage.kt b/app/src/main/java/org/mozilla/fenix/settings/AboutPage.kt deleted file mode 100644 index ebcde6e34..000000000 --- a/app/src/main/java/org/mozilla/fenix/settings/AboutPage.kt +++ /dev/null @@ -1,61 +0,0 @@ -/* - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -package org.mozilla.fenix.settings - -import android.content.Context -import android.content.pm.PackageManager -import androidx.annotation.RawRes -import org.mozilla.fenix.BuildConfig.BUILD_DATE -import org.mozilla.fenix.R -import org.mozilla.fenix.ext.replace -import org.mozilla.fenix.settings.SettingsFragment.Companion.wordmarkPath -import org.mozilla.geckoview.BuildConfig -import java.io.File - -object AboutPage { - fun createAboutPage(context: Context): String { - val substitutionMap = mutableMapOf() - val appName = context.resources.getString(R.string.app_name) - - try { - val packageInfo = context.packageManager.getPackageInfo(context.packageName, 0) - val geckoVersion = packageInfo.versionCode.toString() + " \uD83E\uDD8E " + - BuildConfig.MOZ_APP_VERSION + "-" + BuildConfig.MOZ_APP_BUILDID - String.format( - "%s (Build #%s)", - packageInfo.versionName, - geckoVersion - ).also { aboutVersion -> - substitutionMap["%about-version%"] = aboutVersion - } - } catch (e: PackageManager.NameNotFoundException) { - // Nothing to do if we can't find the package name. - } - - substitutionMap["%build-date%"] = BUILD_DATE - - context.resources.getString(R.string.about_content, appName, SupportUtils.MOZILLA_MANIFESTO_URL) - .also { content -> - substitutionMap["%about-content%"] = content - } - - substitutionMap["%wordmark%"] = File(context.filesDir, wordmarkPath).readText() - - return loadResourceFile(context, R.raw.about, substitutionMap) - } - - private fun loadResourceFile( - context: Context, - @RawRes resId: Int, - replacements: Map - ): String { - context.resources.openRawResource(resId) - .bufferedReader() - .use { it.readText() } - .also { return it.replace(replacements) } - } -} diff --git a/app/src/main/java/org/mozilla/fenix/settings/SettingsFragment.kt b/app/src/main/java/org/mozilla/fenix/settings/SettingsFragment.kt index cf4cabeb7..4b251e97a 100644 --- a/app/src/main/java/org/mozilla/fenix/settings/SettingsFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/settings/SettingsFragment.kt @@ -5,7 +5,6 @@ package org.mozilla.fenix.settings import android.content.Intent -import android.graphics.BitmapFactory import android.net.Uri import android.os.Bundle import android.provider.Settings @@ -18,16 +17,13 @@ import androidx.preference.PreferenceCategory import androidx.preference.PreferenceFragmentCompat import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.Job import kotlinx.coroutines.launch import mozilla.components.concept.sync.AccountObserver import mozilla.components.concept.sync.OAuthAccount import mozilla.components.concept.sync.Profile import kotlin.coroutines.CoroutineContext -import java.io.File import mozilla.components.service.fxa.FxaUnauthorizedException -import mozilla.components.support.ktx.android.graphics.toDataUri import org.mozilla.fenix.BuildConfig import org.mozilla.fenix.FenixApplication import org.mozilla.fenix.HomeActivity @@ -85,7 +81,6 @@ class SettingsFragment : PreferenceFragmentCompat(), CoroutineScope, AccountObse val appName = getString(R.string.app_name) aboutPreference?.title = getString(R.string.preferences_about, appName) - generateWordmark() setupPreferences() setupAccountUI() } @@ -122,8 +117,7 @@ class SettingsFragment : PreferenceFragmentCompat(), CoroutineScope, AccountObse navigateToSettingsArticle() } resources.getString(pref_key_about) -> { - requireComponents.useCases.tabsUseCases.addTab.invoke(aboutURL, true) - navigateToSettingsArticle() + navigateToAbout() } resources.getString(pref_key_account) -> { navigateToAccountSettings() @@ -164,30 +158,6 @@ class SettingsFragment : PreferenceFragmentCompat(), CoroutineScope, AccountObse } } - /** - * Shrinks the wordmark resolution on first run to ensure About Page loads quickly - */ - private fun generateWordmark() { - val path = context?.filesDir - val file = File(path, wordmarkPath) - path?.let { - if (!file.exists()) { - launch(IO) { - val options = BitmapFactory.Options().apply { - inSampleSize = wordmarkScalingFactor - inJustDecodeBounds = false - } - file.appendText( - BitmapFactory.decodeResource( - resources, - R.drawable.ic_logo_wordmark, options - ).toDataUri() - ) - } - } - } - } - private fun setupPreferences() { val makeDefaultBrowserKey = context!!.getPreferenceKey(pref_key_make_default_browser) val leakKey = context!!.getPreferenceKey(pref_key_leakcanary) @@ -263,6 +233,11 @@ class SettingsFragment : PreferenceFragmentCompat(), CoroutineScope, AccountObse } } + private fun navigateToAbout() { + val directions = SettingsFragmentDirections.actionSettingsFragmentToAboutFragment() + Navigation.findNavController(view!!).navigate(directions) + } + private fun navigateToAccountSettings() { val directions = SettingsFragmentDirections.actionSettingsFragmentToAccountSettingsFragment() @@ -319,10 +294,4 @@ class SettingsFragment : PreferenceFragmentCompat(), CoroutineScope, AccountObse preferenceFirefoxAccount?.summary = profile.email.orEmpty() } } - - companion object { - const val wordmarkScalingFactor = 2 - const val wordmarkPath = "wordmark.b64" - const val aboutURL = "about:version" - } } diff --git a/app/src/main/res/layout/fragment_about.xml b/app/src/main/res/layout/fragment_about.xml new file mode 100644 index 000000000..2ddb4d38c --- /dev/null +++ b/app/src/main/res/layout/fragment_about.xml @@ -0,0 +1,59 @@ + + + + + + + + + + + + + diff --git a/app/src/main/res/navigation/nav_graph.xml b/app/src/main/res/navigation/nav_graph.xml index 295febe7c..457de628d 100644 --- a/app/src/main/res/navigation/nav_graph.xml +++ b/app/src/main/res/navigation/nav_graph.xml @@ -106,6 +106,9 @@ + @@ -120,6 +123,11 @@ android:id="@+id/searchEngineFragment" android:name="org.mozilla.fenix.settings.SearchEngineFragment" android:label="SearchEngineFragment" /> + + - - - - - - - -
- -
-

%about-version%

- %about-content% -

Built on: %build-date%

- - diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 349187f9b..e6b7ba958 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -14,7 +14,9 @@ Disable private browsing - Sessions help you return to the sites you visit often and those you\'ve just discovered. Start browsing and they\'ll begin to appear here. + Sessions help you return to the sites you visit often and those you\'ve + just discovered. Start browsing and they\'ll begin to appear here. + Search or enter address @@ -23,7 +25,11 @@ You\'re in a private session - %1$s clears your search and browsing history when you close your private session. While this doesn\'t make you anonymous to websites or your internet service provider, it makes it easier to keep what you do online private from anyone else who uses this device.\n\nCommon myths about private browsing + %1$s clears your search and browsing history when you close your private + session. While this doesn\'t make you anonymous to websites or your internet service provider, it makes it + easier to keep what you do online private from anyone else who uses this device.\n\nCommon myths about private + browsing + Delete session @@ -132,7 +138,9 @@ Optimize - Lower image quality, throttle streaming bandwidth, and platform-level optimizations + Lower image quality, throttle streaming bandwidth, and platform-level + optimizations + Exceptions @@ -141,11 +149,15 @@ Blocked - \n Ads, autoplay sound and video (block playing media with sound), cookies (block third-party trackers cookies), trackers (allow some trackers), pop-up, website redirects. \n\n Ask to allow + \n Ads, autoplay sound and video (block playing media with sound), cookies (block third-party trackers cookies), + trackers (allow some trackers), pop-up, website redirects. \n\n + Ask to allow - \n Camera, location, microphone and notification. \n\n Allowed + \n Camera, location, microphone and notification. \n\n + Allowed - \n DRM audio and video, JavaScript, cache and site data, images. + \n DRM audio and video, JavaScript, cache and site data, images. + Use custom settings @@ -226,11 +238,12 @@ Settings History item menu - - %1$s puts you in control.

-

%1$s is produced by Mozilla. Our mission is to foster a healthy, open Internet.
- ]]> + + + %1$s puts you in control. + \n\n + %1$s is produced by Mozilla. Our mission is to foster a healthy, open Internet. +