AboutFragment.kt 7.81 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
/* 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.about

import android.content.Intent
import android.content.pm.PackageManager
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.content.pm.PackageInfoCompat
import androidx.fragment.app.Fragment
15
import androidx.navigation.fragment.findNavController
16
17
import androidx.recyclerview.widget.DividerItemDecoration
import kotlinx.android.synthetic.main.fragment_about.*
18
import org.mozilla.fenix.BrowserDirection
19
import org.mozilla.fenix.BuildConfig
20
import org.mozilla.fenix.Config
21
import org.mozilla.fenix.HomeActivity
22
23
import org.mozilla.fenix.R
import org.mozilla.fenix.components.metrics.Event
24
import org.mozilla.fenix.crashes.CrashListActivity
25
import org.mozilla.fenix.ext.requireComponents
26
import org.mozilla.fenix.ext.settings
27
28
29
30
31
32
import org.mozilla.fenix.settings.SupportUtils
import org.mozilla.fenix.settings.about.AboutItemType.LICENSING_INFO
import org.mozilla.fenix.settings.about.AboutItemType.PRIVACY_NOTICE
import org.mozilla.fenix.settings.about.AboutItemType.RIGHTS
import org.mozilla.fenix.settings.about.AboutItemType.SUPPORT
import org.mozilla.fenix.settings.about.AboutItemType.WHATS_NEW
33
import org.mozilla.fenix.utils.Do
34
35
36
37
38
39
40
import org.mozilla.fenix.whatsnew.WhatsNew
import org.mozilla.geckoview.BuildConfig as GeckoViewBuildConfig

/**
 * Displays the logo and information about the app, including library versions.
 */
class AboutFragment : Fragment(), AboutPageListener {
41

42
    private lateinit var headerAppName: String
43
    private lateinit var appName: String
44
    private var aboutPageAdapter: AboutPageAdapter? = AboutPageAdapter(this)
45
46
47
48
49
50
51
52

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val rootView = inflater.inflate(R.layout.fragment_about, container, false)
        appName = getString(R.string.app_name)
53
54
        headerAppName =
            if (Config.channel.isRelease) getString(R.string.daylight_app_name) else appName
55
56
57
58
59
60
        activity?.title = getString(R.string.preferences_about, appName)

        return rootView
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
61
62
63
64
        if (aboutPageAdapter == null) {
            aboutPageAdapter = AboutPageAdapter(this)
        }

65
66
67
68
69
70
71
72
73
74
        about_list.run {
            adapter = aboutPageAdapter
            addItemDecoration(
                DividerItemDecoration(
                    context,
                    DividerItemDecoration.VERTICAL
                )
            )
        }

75
76
77
78
79
80
        lifecycle.addObserver(
            SecretDebugMenuTrigger(
                logoView = wordmark,
                settings = view.context.settings()
            )
        )
81

82
        populateAboutHeader()
83
84
85
86
87
88
        aboutPageAdapter?.submitList(populateAboutList())
    }

    override fun onDestroyView() {
        super.onDestroyView()
        aboutPageAdapter = null
89
90
91
92
    }

    private fun populateAboutHeader() {
        val aboutText = try {
93
94
            val packageInfo =
                requireContext().packageManager.getPackageInfo(requireContext().packageName, 0)
95
            val versionCode = PackageInfoCompat.getLongVersionCode(packageInfo).toString()
96
            val componentsAbbreviation = getString(R.string.components_abbreviation)
97
98
            val componentsVersion =
                mozilla.components.Build.version + ", " + mozilla.components.Build.gitHash
99
            val maybeGecko = getString(R.string.gecko_view_abbreviation)
100
101
            val geckoVersion =
                GeckoViewBuildConfig.MOZ_APP_VERSION + "-" + GeckoViewBuildConfig.MOZ_APP_BUILDID
102
103
            val appServicesAbbreviation = getString(R.string.app_services_abbreviation)
            val appServicesVersion = mozilla.components.Build.applicationServicesVersion
104
105

            String.format(
106
                "%s (Build #%s)\n%s: %s\n%s: %s\n%s: %s",
107
108
                packageInfo.versionName,
                versionCode,
109
                componentsAbbreviation,
110
111
                componentsVersion,
                maybeGecko,
112
113
114
                geckoVersion,
                appServicesAbbreviation,
                appServicesVersion
115
116
117
118
119
            )
        } catch (e: PackageManager.NameNotFoundException) {
            ""
        }

120
        val content = getString(R.string.about_content, headerAppName)
121
122
123
124
125
126
127
128
129
130
131
        val buildDate = BuildConfig.BUILD_DATE

        about_text.text = aboutText
        about_content.text = content
        build_date.text = buildDate
    }

    private fun populateAboutList(): List<AboutPageItem> {
        val context = requireContext()

        return listOf(
132
            AboutPageItem(
133
134
                AboutItem.ExternalLink(
                    WHATS_NEW,
135
                    SupportUtils.getWhatsNewUrl(context)
136
137
                ), getString(R.string.about_whats_new, getString(R.string.app_name))
            ),
138
            AboutPageItem(
139
140
                AboutItem.ExternalLink(
                    SUPPORT,
141
                    SupportUtils.getTorHelpPageUrl()
142
143
                ), getString(R.string.about_support)
            ),
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
            // AboutPageItem(
            //     AboutItem.Crashes,
            //     getString(R.string.about_crashes)
            // ),
            // AboutPageItem(
            //     AboutItem.ExternalLink(
            //         PRIVACY_NOTICE,
            //         SupportUtils.getMozillaPageUrl(SupportUtils.MozillaPage.PRIVATE_NOTICE)
            //     ), getString(R.string.about_privacy_notice)
            // ),
            // AboutPageItem(
            //     AboutItem.ExternalLink(
            //         RIGHTS,
            //         SupportUtils.getSumoURLForTopic(context, SupportUtils.SumoTopic.YOUR_RIGHTS)
            //     ), getString(R.string.about_know_your_rights)
            // ),
160
            AboutPageItem(
161
162
163
                AboutItem.ExternalLink(LICENSING_INFO, ABOUT_LICENSE_URL),
                getString(R.string.about_licensing_information)
            ),
164
            AboutPageItem(
165
166
167
168
169
170
                AboutItem.Libraries,
                getString(R.string.about_other_open_source_libraries)
            )
        )
    }

171
172
173
174
175
176
    private fun openLinkInNormalTab(url: String) {
        (activity as HomeActivity).openToBrowserAndLoad(
            searchTermOrURL = url,
            newTab = true,
            from = BrowserDirection.FromAbout
        )
177
178
179
    }

    private fun openLibrariesPage() {
180
181
        val navController = findNavController()
        navController.navigate(R.id.action_aboutFragment_to_aboutLibrariesFragment)
182
183
184
185
186
    }

    override fun onAboutItemClicked(item: AboutItem) {
        Do exhaustive when (item) {
            is AboutItem.ExternalLink -> {
187
188
189
190
191
192
193
194
195
196
197
                when (item.type) {
                    WHATS_NEW -> {
                        WhatsNew.userViewedWhatsNew(requireContext())
                        requireComponents.analytics.metrics.track(Event.WhatsNewTapped)
                    }
                    SUPPORT -> {
                        requireComponents.analytics.metrics.track(Event.SupportTapped)
                    }
                    PRIVACY_NOTICE -> {
                        requireComponents.analytics.metrics.track(Event.PrivacyNoticeTapped)
                    }
198
                    LICENSING_INFO, RIGHTS -> {} // no telemetry needed
199
200
                }

201
                openLinkInNormalTab(item.url)
202
203
204
205
            }
            is AboutItem.Libraries -> {
                openLibrariesPage()
            }
206
207
208
            is AboutItem.Crashes -> {
                startActivity(Intent(requireContext(), CrashListActivity::class.java))
            }
209
210
211
212
213
214
215
        }
    }

    companion object {
        private const val ABOUT_LICENSE_URL = "about:license"
    }
}