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.app.Activity;
23 import android.app.Dialog;
24 import android.content.Intent;
25 import android.content.SharedPreferences;
26 import android.net.Uri;
27 import android.os.Bundle;
28 import android.preference.PreferenceManager;
29 import android.view.WindowManager;
30 import android.widget.EditText;
31 import android.widget.LinearLayout;
33 import androidx.appcompat.app.ActionBar;
34 import androidx.appcompat.app.AppCompatActivity;
35 import androidx.appcompat.widget.Toolbar;
36 import androidx.fragment.app.DialogFragment;
37 import androidx.viewpager.widget.ViewPager;
39 import com.google.android.material.snackbar.Snackbar;
40 import com.google.android.material.tabs.TabLayout;
42 import com.stoutner.privacybrowser.adapters.AboutPagerAdapter;
43 import com.stoutner.privacybrowser.R;
44 import com.stoutner.privacybrowser.asynctasks.SaveAboutVersionImage;
45 import com.stoutner.privacybrowser.dialogs.SaveDialog;
46 import com.stoutner.privacybrowser.fragments.AboutVersionFragment;
48 import java.io.BufferedReader;
49 import java.io.BufferedWriter;
50 import java.io.ByteArrayInputStream;
51 import java.io.InputStream;
52 import java.io.InputStreamReader;
53 import java.io.OutputStream;
54 import java.io.OutputStreamWriter;
55 import java.nio.charset.StandardCharsets;
57 public class AboutActivity extends AppCompatActivity implements SaveDialog.SaveListener {
58 // Declare the class variables.
59 private AboutPagerAdapter aboutPagerAdapter;
62 protected void onCreate(Bundle savedInstanceState) {
63 // Get a handle for the shared preferences.
64 SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
66 // Get the screenshot preference.
67 boolean allowScreenshots = sharedPreferences.getBoolean(getString(R.string.allow_screenshots_key), false);
69 // Disable screenshots if not allowed.
70 if (!allowScreenshots) {
71 getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE);
75 setTheme(R.style.PrivacyBrowser);
77 // Run the default commands.
78 super.onCreate(savedInstanceState);
80 // Get the intent that launched the activity.
81 Intent launchingIntent = getIntent();
83 // Store the blocklist versions.
84 String[] blocklistVersions = launchingIntent.getStringArrayExtra("blocklist_versions");
86 // Remove the incorrect lint warning below that the blocklist versions might be null.
87 assert blocklistVersions != null;
89 // Set the content view.
90 setContentView(R.layout.about_coordinatorlayout);
92 // Get handles for the views.
93 Toolbar toolbar = findViewById(R.id.about_toolbar);
94 TabLayout aboutTabLayout = findViewById(R.id.about_tablayout);
95 ViewPager aboutViewPager = findViewById(R.id.about_viewpager);
97 // Set the action bar. `SupportActionBar` must be used until the minimum API is >= 21.
98 setSupportActionBar(toolbar);
100 // Get a handle for the action bar.
101 final ActionBar actionBar = getSupportActionBar();
103 // Remove the incorrect lint warning that the action bar might be null.
104 assert actionBar != null; //
106 // Display the home arrow on action bar.
107 actionBar.setDisplayHomeAsUpEnabled(true);
109 // Initialize the about pager adapter.
110 aboutPagerAdapter = new AboutPagerAdapter(getSupportFragmentManager(), getApplicationContext(), blocklistVersions);
112 // Setup the ViewPager.
113 aboutViewPager.setAdapter(aboutPagerAdapter);
115 // Keep all the tabs in memory. This prevents the memory usage updater from running multiple times.
116 aboutViewPager.setOffscreenPageLimit(10);
118 // Connect the tab layout to the view pager.
119 aboutTabLayout.setupWithViewPager(aboutViewPager);
122 // The activity result is called after browsing for a file in the save alert dialog.
124 public void onActivityResult(int requestCode, int resultCode, Intent returnedIntent) {
125 // Run the default commands.
126 super.onActivityResult(requestCode, resultCode, returnedIntent);
128 // Only do something if the user didn't press back from the file picker.
129 if (resultCode == Activity.RESULT_OK) {
130 // Get a handle for the save dialog fragment.
131 DialogFragment saveDialogFragment = (DialogFragment) getSupportFragmentManager().findFragmentByTag(getString(R.string.save_dialog));
133 // Only update the file name if the dialog still exists.
134 if (saveDialogFragment != null) {
135 // Get a handle for the save dialog.
136 Dialog saveDialog = saveDialogFragment.getDialog();
138 // Remove the lint warning below that the dialog might be null.
139 assert saveDialog != null;
141 // Get a handle for the dialog view.
142 EditText fileNameEditText = saveDialog.findViewById(R.id.file_name_edittext);
144 // Get the file name URI from the intent.
145 Uri fileNameUri = returnedIntent.getData();
147 // Get the file name string from the URI.
148 String fileNameString = fileNameUri.toString();
150 // Set the file name text.
151 fileNameEditText.setText(fileNameString);
153 // Move the cursor to the end of the file name edit text.
154 fileNameEditText.setSelection(fileNameString.length());
160 public void onSave(int saveType, DialogFragment dialogFragment) {
161 // Get a handle for the dialog.
162 Dialog dialog = dialogFragment.getDialog();
164 // Remove the lint warning below that the dialog might be null.
165 assert dialog != null;
167 // Get a handle for the file name edit text.
168 EditText fileNameEditText = dialog.findViewById(R.id.file_name_edittext);
170 // Get the file name string.
171 String fileNameString = fileNameEditText.getText().toString();
173 // Get a handle for the about version linear layout.
174 LinearLayout aboutVersionLinearLayout = findViewById(R.id.about_version_linearlayout);
176 // Save the file according to the type.
178 case SaveDialog.SAVE_ABOUT_VERSION_TEXT:
180 // Get a handle for the about version fragment.
181 AboutVersionFragment aboutVersionFragment = (AboutVersionFragment) aboutPagerAdapter.getTabFragment(0);
183 // Get the about version text.
184 String aboutVersionString = aboutVersionFragment.getAboutVersionString();
186 // Create an input stream with the contents of about version.
187 InputStream aboutVersionInputStream = new ByteArrayInputStream(aboutVersionString.getBytes(StandardCharsets.UTF_8));
189 // Create an about version buffered reader.
190 BufferedReader aboutVersionBufferedReader = new BufferedReader(new InputStreamReader(aboutVersionInputStream));
192 // Open an output stream.
193 OutputStream outputStream = getContentResolver().openOutputStream(Uri.parse(fileNameString));
195 // Create a file buffered writer.
196 BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream));
198 // Create a transfer string.
199 String transferString;
201 // Use the transfer string to copy the about version text from the buffered reader to the buffered writer.
202 while ((transferString = aboutVersionBufferedReader.readLine()) != null) {
203 // Append the line to the buffered writer.
204 bufferedWriter.append(transferString);
206 // Append a line break.
207 bufferedWriter.append("\n");
210 // Flush the buffered writer.
211 bufferedWriter.flush();
213 // Close the inputs and outputs.
214 aboutVersionBufferedReader.close();
215 aboutVersionInputStream.close();
216 bufferedWriter.close();
217 outputStream.close();
219 // Display a snackbar with the saved about version information.
220 Snackbar.make(aboutVersionLinearLayout, getString(R.string.file_saved) + " " + fileNameString, Snackbar.LENGTH_SHORT).show();
221 } catch (Exception exception) {
222 // Display a snackbar with the error message.
223 Snackbar.make(aboutVersionLinearLayout, getString(R.string.error_saving_file) + " " + exception.toString(), Snackbar.LENGTH_INDEFINITE).show();
227 case SaveDialog.SAVE_ABOUT_VERSION_IMAGE:
228 // Save the about version image.
229 new SaveAboutVersionImage(this, fileNameString, aboutVersionLinearLayout).execute();