2 * Copyright © 2016-2021 Soren Stoutner <soren@stoutner.com>.
4 * This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
6 * Privacy Browser is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * Privacy Browser is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with Privacy Browser. If not, see <http://www.gnu.org/licenses/>.
20 package com.stoutner.privacybrowser.activities
22 import android.content.Intent
23 import android.net.Uri
24 import android.os.Bundle
25 import android.view.WindowManager
26 import android.widget.EditText
27 import android.widget.LinearLayout
29 import androidx.appcompat.app.AppCompatActivity
30 import androidx.appcompat.widget.Toolbar
31 import androidx.fragment.app.DialogFragment
32 import androidx.preference.PreferenceManager
33 import androidx.viewpager.widget.ViewPager
35 import com.google.android.material.snackbar.Snackbar
36 import com.google.android.material.tabs.TabLayout
38 import com.stoutner.privacybrowser.R
39 import com.stoutner.privacybrowser.adapters.AboutPagerAdapter
40 import com.stoutner.privacybrowser.asynctasks.SaveAboutVersionImage
41 import com.stoutner.privacybrowser.dialogs.SaveDialog
42 import com.stoutner.privacybrowser.dialogs.SaveDialog.SaveListener
43 import com.stoutner.privacybrowser.fragments.AboutVersionFragment
45 import java.io.ByteArrayInputStream
46 import java.io.InputStream
47 import java.lang.Exception
48 import java.nio.charset.StandardCharsets
50 class AboutActivity : AppCompatActivity(), SaveListener {
51 // Declare the class variables.
52 private lateinit var aboutPagerAdapter: AboutPagerAdapter
55 // Define the companion object constants. These can be move to being public constants once MainWebViewActivity has been converted to Kotlin.
56 const val BLOCKLIST_VERSIONS = "blocklist_versions"
59 override fun onCreate(savedInstanceState: Bundle?) {
60 // Get a handle for the shared preferences.
61 val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this)
63 // Get the screenshot preference.
64 val allowScreenshots = sharedPreferences.getBoolean(getString(R.string.allow_screenshots_key), false)
66 // Disable screenshots if not allowed.
67 if (!allowScreenshots) {
68 window.addFlags(WindowManager.LayoutParams.FLAG_SECURE)
72 setTheme(R.style.PrivacyBrowser)
74 // Run the default commands.
75 super.onCreate(savedInstanceState)
77 // Get the intent that launched the activity.
78 val launchingIntent = intent
80 // Store the blocklist versions.
81 val blocklistVersions = launchingIntent.getStringArrayExtra(BLOCKLIST_VERSIONS)!!
83 // Set the content view.
84 setContentView(R.layout.about_coordinatorlayout)
86 // Get handles for the views.
87 val toolbar = findViewById<Toolbar>(R.id.about_toolbar)
88 val aboutTabLayout = findViewById<TabLayout>(R.id.about_tablayout)
89 val aboutViewPager = findViewById<ViewPager>(R.id.about_viewpager)
91 // Set the action bar. `SupportActionBar` must be used until the minimum API is >= 21.
92 setSupportActionBar(toolbar)
94 // Get a handle for the action bar.
95 val actionBar = supportActionBar!!
97 // Display the home arrow on action bar.
98 actionBar.setDisplayHomeAsUpEnabled(true)
100 // Initialize the about pager adapter.
101 aboutPagerAdapter = AboutPagerAdapter(supportFragmentManager, applicationContext, blocklistVersions)
103 // Set the view pager adapter.
104 aboutViewPager.adapter = aboutPagerAdapter
106 // Keep all the tabs in memory. This prevents the memory usage updater from running multiple times.
107 aboutViewPager.offscreenPageLimit = 10
109 // Connect the tab layout to the view pager.
110 aboutTabLayout.setupWithViewPager(aboutViewPager)
113 // The activity result is called after browsing for a file in the save alert dialog.
114 public override fun onActivityResult(requestCode: Int, resultCode: Int, returnedIntent: Intent?) {
115 // Run the default commands.
116 super.onActivityResult(requestCode, resultCode, returnedIntent)
118 // Only do something if the user didn't press back from the file picker.
119 if (resultCode == RESULT_OK) {
120 // Get a handle for the save dialog fragment.
121 val saveDialogFragment = supportFragmentManager.findFragmentByTag(getString(R.string.save_dialog)) as DialogFragment?
123 // Only update the file name if the dialog still exists.
124 if (saveDialogFragment != null) {
125 // Get a handle for the save dialog.
126 val saveDialog = saveDialogFragment.dialog!!
128 // Get a handle for the file name edit text.
129 val fileNameEditText = saveDialog.findViewById<EditText>(R.id.file_name_edittext)
131 // Get the file name URI from the intent.
132 val fileNameUri = returnedIntent!!.data
134 // Get the file name string from the URI.
135 val fileNameString = fileNameUri.toString()
137 // Set the file name text.
138 fileNameEditText.setText(fileNameString)
140 // Move the cursor to the end of the file name edit text.
141 fileNameEditText.setSelection(fileNameString.length)
146 override fun onSave(saveType: Int, dialogFragment: DialogFragment) {
147 // Get a handle for the dialog.
148 val dialog = dialogFragment.dialog!!
150 // Get a handle for the file name edit text.
151 val fileNameEditText = dialog.findViewById<EditText>(R.id.file_name_edittext)
153 // Get the file name string.
154 val fileNameString = fileNameEditText.text.toString()
156 // Get a handle for the about version linear layout.
157 val aboutVersionLinearLayout = findViewById<LinearLayout>(R.id.about_version_linearlayout)
159 // Process the save event according to the type.
161 SaveDialog.SAVE_ABOUT_VERSION_TEXT -> try {
162 // Get a handle for the about version fragment.
163 val aboutVersionFragment = aboutPagerAdapter.getTabFragment(0) as AboutVersionFragment
165 // Get the about version text.
166 val aboutVersionString = aboutVersionFragment.aboutVersionString
168 // Create an input stream with the contents of about version.
169 val aboutVersionInputStream: InputStream = ByteArrayInputStream(aboutVersionString.toByteArray(StandardCharsets.UTF_8))
171 // Open an output stream.
172 val outputStream = contentResolver.openOutputStream(Uri.parse(fileNameString))!!
174 // Copy the input stream to the output stream.
175 aboutVersionInputStream.copyTo(outputStream, 2048)
177 // Close the streams.
178 aboutVersionInputStream.close()
181 // Display a snackbar with the saved about version information.
182 Snackbar.make(aboutVersionLinearLayout, getString(R.string.file_saved) + " " + fileNameString, Snackbar.LENGTH_SHORT).show()
183 } catch (exception: Exception) {
184 // Display a snackbar with the error message.
185 Snackbar.make(aboutVersionLinearLayout, getString(R.string.error_saving_file) + " " + exception.toString(), Snackbar.LENGTH_INDEFINITE).show()
188 SaveDialog.SAVE_ABOUT_VERSION_IMAGE ->
189 // Save the about version image.
190 SaveAboutVersionImage(this, fileNameString, aboutVersionLinearLayout).execute()