From 0c8b2a8a1ee435fbce3e5a3ca33745fe60ce846e Mon Sep 17 00:00:00 2001
From: Emily Kager
Date: Tue, 12 Feb 2019 11:13:09 -0800
Subject: [PATCH] Closes #449 - Adds Basic About Page with Dated Version Name
---
app/build.gradle | 8 +--
.../mozilla/fenix/AppRequestInterceptor.kt | 41 ++++++++++++++
.../java/org/mozilla/fenix/components/Core.kt | 2 +
.../main/java/org/mozilla/fenix/ext/String.kt | 16 ++++++
.../org/mozilla/fenix/settings/AboutPage.kt | 53 +++++++++++++++++++
.../fenix/settings/SettingsFragment.kt | 29 +++++++++-
app/src/main/res/raw/about.html | 49 +++++++++++++++++
app/src/main/res/values/strings.xml | 6 +++
buildSrc/src/main/java/Config.kt | 27 ++++++++++
9 files changed, 226 insertions(+), 5 deletions(-)
create mode 100644 app/src/main/java/org/mozilla/fenix/AppRequestInterceptor.kt
create mode 100644 app/src/main/java/org/mozilla/fenix/ext/String.kt
create mode 100644 app/src/main/java/org/mozilla/fenix/settings/AboutPage.kt
create mode 100644 app/src/main/res/raw/about.html
create mode 100644 buildSrc/src/main/java/Config.kt
diff --git a/app/build.gradle b/app/build.gradle
index 91969d20f..9df434e57 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -12,10 +12,10 @@ android {
compileSdkVersion 28
defaultConfig {
applicationId "org.mozilla.fenix"
- minSdkVersion 21
- targetSdkVersion 28
- versionCode 1
- versionName "1.0"
+ minSdkVersion Config.minSdkVersion
+ targetSdkVersion Config.targetSdkVersion
+ versionCode Config.versionCode
+ versionName Config.versionName + Config.generateVersionSuffix()
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
diff --git a/app/src/main/java/org/mozilla/fenix/AppRequestInterceptor.kt b/app/src/main/java/org/mozilla/fenix/AppRequestInterceptor.kt
new file mode 100644
index 000000000..121ed5559
--- /dev/null
+++ b/app/src/main/java/org/mozilla/fenix/AppRequestInterceptor.kt
@@ -0,0 +1,41 @@
+/* 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
+
+import android.content.Context
+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.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 -> null
+ }
+ }
+
+ override fun onErrorRequest(
+ session: EngineSession,
+ errorType: ErrorType,
+ uri: String?
+ ): 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/components/Core.kt b/app/src/main/java/org/mozilla/fenix/components/Core.kt
index de81ba774..cc9c18f42 100644
--- a/app/src/main/java/org/mozilla/fenix/components/Core.kt
+++ b/app/src/main/java/org/mozilla/fenix/components/Core.kt
@@ -16,6 +16,7 @@ import mozilla.components.concept.engine.Engine
import mozilla.components.concept.engine.EngineSession.TrackingProtectionPolicy
import mozilla.components.feature.session.HistoryDelegate
import mozilla.components.lib.crash.handler.CrashHandlerService
+import org.mozilla.fenix.AppRequestInterceptor
import org.mozilla.geckoview.GeckoRuntime
import org.mozilla.geckoview.GeckoRuntimeSettings
@@ -32,6 +33,7 @@ class Core(private val context: Context) {
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
val defaultSettings = DefaultSettings(
+ requestInterceptor = AppRequestInterceptor(context),
remoteDebuggingEnabled = false,
testingModeEnabled = false,
trackingProtectionPolicy = createTrackingProtectionPolicy(prefs),
diff --git a/app/src/main/java/org/mozilla/fenix/ext/String.kt b/app/src/main/java/org/mozilla/fenix/ext/String.kt
new file mode 100644
index 000000000..04421f26f
--- /dev/null
+++ b/app/src/main/java/org/mozilla/fenix/ext/String.kt
@@ -0,0 +1,16 @@
+/*
+ * 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
+
+/**
+ * Replaces the keys with the values with the map provided.
+ */
+fun String.replace(pairs: Map): String {
+ var result = this
+ pairs.forEach { (l, r) -> result = result.replace(l, r) }
+ return result
+}
diff --git a/app/src/main/java/org/mozilla/fenix/settings/AboutPage.kt b/app/src/main/java/org/mozilla/fenix/settings/AboutPage.kt
new file mode 100644
index 000000000..250779625
--- /dev/null
+++ b/app/src/main/java/org/mozilla/fenix/settings/AboutPage.kt
@@ -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.settings
+
+import android.content.Context
+import android.content.pm.PackageManager
+import androidx.annotation.RawRes
+import org.mozilla.fenix.R
+import org.mozilla.fenix.ext.replace
+import org.mozilla.geckoview.BuildConfig
+
+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.
+ }
+
+ context.resources.getString(R.string.about_content, appName).also { content ->
+ substitutionMap["%about-content%"] = content
+ }
+
+ 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 7992a5ba3..3be68ac2c 100644
--- a/app/src/main/java/org/mozilla/fenix/settings/SettingsFragment.kt
+++ b/app/src/main/java/org/mozilla/fenix/settings/SettingsFragment.kt
@@ -9,12 +9,16 @@ import android.os.Bundle
import android.provider.Settings
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
+import androidx.navigation.Navigation
import androidx.preference.Preference
import androidx.preference.Preference.OnPreferenceClickListener
import androidx.preference.PreferenceFragmentCompat
+import mozilla.components.browser.session.Session
import org.mozilla.fenix.R
+import org.mozilla.fenix.R.string.pref_key_about
import org.mozilla.fenix.R.string.pref_key_make_default_browser
import org.mozilla.fenix.ext.getPreferenceKey
+import org.mozilla.fenix.ext.requireComponents
class SettingsFragment : PreferenceFragmentCompat() {
@@ -35,10 +39,14 @@ class SettingsFragment : PreferenceFragmentCompat() {
private fun setupPreferences() {
val makeDefaultBrowserKey = context?.getPreferenceKey(pref_key_make_default_browser)
+ val aboutKey = context?.getPreferenceKey(pref_key_about)
val preferenceMakeDefaultBrowser = findPreference(makeDefaultBrowserKey)
+ val preferenceAbout = findPreference(aboutKey)
- preferenceMakeDefaultBrowser.onPreferenceClickListener = getClickListenerForMakeDefaultBrowser()
+ preferenceMakeDefaultBrowser.onPreferenceClickListener =
+ getClickListenerForMakeDefaultBrowser()
+ preferenceAbout.onPreferenceClickListener = getAboutPageListener()
}
private val defaultClickListener = OnPreferenceClickListener { preference ->
@@ -59,4 +67,23 @@ class SettingsFragment : PreferenceFragmentCompat() {
defaultClickListener
}
}
+
+ private fun getAboutPageListener(): OnPreferenceClickListener {
+ return OnPreferenceClickListener {
+ requireComponents.core.sessionManager.add(Session(aboutURL), true)
+ view?.let {
+ Navigation.findNavController(it)
+ .navigate(
+ SettingsFragmentDirections.actionGlobalBrowser(
+ requireComponents.core.sessionManager.selectedSession?.id
+ )
+ )
+ }
+ true
+ }
+ }
+
+ companion object {
+ const val aboutURL = "about:version"
+ }
}
diff --git a/app/src/main/res/raw/about.html b/app/src/main/res/raw/about.html
new file mode 100644
index 000000000..0396efb8d
--- /dev/null
+++ b/app/src/main/res/raw/about.html
@@ -0,0 +1,49 @@
+
+
+
+
+
+
+
+
+ Fenix
+ %about-version%
+ %about-content%
+
+
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 0ef5b0c19..f2802a0f6 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -131,4 +131,10 @@
History item menu
+
+
+ %1$s puts you in control.
+%1$s is produced by Mozilla. Our mission is to foster a healthy, open Internet.
+ ]]>
diff --git a/buildSrc/src/main/java/Config.kt b/buildSrc/src/main/java/Config.kt
new file mode 100644
index 000000000..616695148
--- /dev/null
+++ b/buildSrc/src/main/java/Config.kt
@@ -0,0 +1,27 @@
+import java.text.SimpleDateFormat
+import java.util.Date
+import java.util.Locale
+
+/* 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/. */
+
+object Config {
+ const val versionCode = 1
+ const val versionName = "1.0"
+
+ // Synchronized build configuration for all modules
+ const val compileSdkVersion = 28
+ const val minSdkVersion = 21
+ const val targetSdkVersion = 28
+
+ @JvmStatic
+ fun generateVersionSuffix(): String {
+ val today = Date()
+ // Append the year (2 digits) and week in year (2 digits). This will make it easier to distinguish versions and
+ // identify ancient versions when debugging issues. However this will still keep the same version number during
+ // the week so that we do not end up with a lot of versions in tools like Sentry. As an extra this matches the
+ // sections we use in the changelog (weeks).
+ return SimpleDateFormat(".yyww", Locale.US).format(today)
+ }
+}