Add the option to move the app bar to the bottom of the screen. https://redmine.stout...
[PrivacyBrowser.git] / app / src / main / java / com / stoutner / privacybrowser / activities / AboutActivity.kt
1 /*
2  * Copyright © 2016-2021 Soren Stoutner <soren@stoutner.com>.
3  *
4  * This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
5  *
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.
10  *
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.
15  *
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/>.
18  */
19
20 package com.stoutner.privacybrowser.activities
21
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
28
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
34
35 import com.google.android.material.snackbar.Snackbar
36 import com.google.android.material.tabs.TabLayout
37
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
44
45 import java.io.ByteArrayInputStream
46 import java.io.InputStream
47 import java.lang.Exception
48 import java.nio.charset.StandardCharsets
49
50 class AboutActivity : AppCompatActivity(), SaveListener {
51     // Declare the class variables.
52     private lateinit var aboutPagerAdapter: AboutPagerAdapter
53
54     companion object {
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"
57     }
58
59     override fun onCreate(savedInstanceState: Bundle?) {
60         // Get a handle for the shared preferences.
61         val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this)
62
63         // Get the preferences.
64         val allowScreenshots = sharedPreferences.getBoolean(getString(R.string.allow_screenshots_key), false)
65         val bottomAppBar = sharedPreferences.getBoolean(getString(R.string.bottom_app_bar_key), false)
66
67         // Disable screenshots if not allowed.
68         if (!allowScreenshots) {
69             window.addFlags(WindowManager.LayoutParams.FLAG_SECURE)
70         }
71
72         // Set the theme.
73         setTheme(R.style.PrivacyBrowser)
74
75         // Run the default commands.
76         super.onCreate(savedInstanceState)
77
78         // Get the intent that launched the activity.
79         val launchingIntent = intent
80
81         // Store the blocklist versions.
82         val blocklistVersions = launchingIntent.getStringArrayExtra(BLOCKLIST_VERSIONS)!!
83
84         // Set the content view.
85         if (bottomAppBar) {
86             setContentView(R.layout.about_coordinatorlayout_bottom_appbar)
87         } else {
88             setContentView(R.layout.about_coordinatorlayout_top_appbar)
89         }
90
91         // Get handles for the views.
92         val toolbar = findViewById<Toolbar>(R.id.about_toolbar)
93         val aboutTabLayout = findViewById<TabLayout>(R.id.about_tablayout)
94         val aboutViewPager = findViewById<ViewPager>(R.id.about_viewpager)
95
96         // Set the action bar.  `SupportActionBar` must be used until the minimum API is >= 21.
97         setSupportActionBar(toolbar)
98
99         // Get a handle for the action bar.
100         val actionBar = supportActionBar!!
101
102         // Display the home arrow on action bar.
103         actionBar.setDisplayHomeAsUpEnabled(true)
104
105         // Initialize the about pager adapter.
106         aboutPagerAdapter = AboutPagerAdapter(supportFragmentManager, applicationContext, blocklistVersions)
107
108         // Set the view pager adapter.
109         aboutViewPager.adapter = aboutPagerAdapter
110
111         // Keep all the tabs in memory.  This prevents the memory usage updater from running multiple times.
112         aboutViewPager.offscreenPageLimit = 10
113
114         // Connect the tab layout to the view pager.
115         aboutTabLayout.setupWithViewPager(aboutViewPager)
116     }
117
118     // The activity result is called after browsing for a file in the save alert dialog.
119     public override fun onActivityResult(requestCode: Int, resultCode: Int, returnedIntent: Intent?) {
120         // Run the default commands.
121         super.onActivityResult(requestCode, resultCode, returnedIntent)
122
123         // Only do something if the user didn't press back from the file picker.
124         if (resultCode == RESULT_OK) {
125             // Get a handle for the save dialog fragment.
126             val saveDialogFragment = supportFragmentManager.findFragmentByTag(getString(R.string.save_dialog)) as DialogFragment?
127
128             // Only update the file name if the dialog still exists.
129             if (saveDialogFragment != null) {
130                 // Get a handle for the save dialog.
131                 val saveDialog = saveDialogFragment.dialog!!
132
133                 // Get a handle for the file name edit text.
134                 val fileNameEditText = saveDialog.findViewById<EditText>(R.id.file_name_edittext)
135
136                 // Get the file name URI from the intent.
137                 val fileNameUri = returnedIntent!!.data
138
139                 // Get the file name string from the URI.
140                 val fileNameString = fileNameUri.toString()
141
142                 // Set the file name text.
143                 fileNameEditText.setText(fileNameString)
144
145                 // Move the cursor to the end of the file name edit text.
146                 fileNameEditText.setSelection(fileNameString.length)
147             }
148         }
149     }
150
151     override fun onSave(saveType: Int, dialogFragment: DialogFragment) {
152         // Get a handle for the dialog.
153         val dialog = dialogFragment.dialog!!
154
155         // Get a handle for the file name edit text.
156         val fileNameEditText = dialog.findViewById<EditText>(R.id.file_name_edittext)
157
158         // Get the file name string.
159         val fileNameString = fileNameEditText.text.toString()
160
161         // Get a handle for the about version linear layout.
162         val aboutVersionLinearLayout = findViewById<LinearLayout>(R.id.about_version_linearlayout)
163
164         // Process the save event according to the type.
165         when (saveType) {
166             SaveDialog.SAVE_ABOUT_VERSION_TEXT -> try {
167                 // Get a handle for the about version fragment.
168                 val aboutVersionFragment = aboutPagerAdapter.getTabFragment(0) as AboutVersionFragment
169
170                 // Get the about version text.
171                 val aboutVersionString = aboutVersionFragment.aboutVersionString
172
173                 // Create an input stream with the contents of about version.
174                 val aboutVersionInputStream: InputStream = ByteArrayInputStream(aboutVersionString.toByteArray(StandardCharsets.UTF_8))
175
176                 // Open an output stream.
177                 val outputStream = contentResolver.openOutputStream(Uri.parse(fileNameString))!!
178
179                 // Copy the input stream to the output stream.
180                 aboutVersionInputStream.copyTo(outputStream, 2048)
181
182                 // Close the streams.
183                 aboutVersionInputStream.close()
184                 outputStream.close()
185
186                 // Display a snackbar with the saved about version information.
187                 Snackbar.make(aboutVersionLinearLayout, getString(R.string.file_saved) + "  " + fileNameString, Snackbar.LENGTH_SHORT).show()
188             } catch (exception: Exception) {
189                 // Display a snackbar with the error message.
190                 Snackbar.make(aboutVersionLinearLayout, getString(R.string.error_saving_file) + "  " + exception.toString(), Snackbar.LENGTH_INDEFINITE).show()
191             }
192
193             SaveDialog.SAVE_ABOUT_VERSION_IMAGE ->
194                 // Save the about version image.
195                 SaveAboutVersionImage(this, fileNameString, aboutVersionLinearLayout).execute()
196         }
197     }
198 }