31e9c152f5d7e71338a5812d6fe13720d909cead
[PrivacyBrowser.git] / app / src / main / java / com / stoutner / privacybrowser / activities / AboutActivity.java
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.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;
32
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;
38
39 import com.google.android.material.snackbar.Snackbar;
40 import com.google.android.material.tabs.TabLayout;
41
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;
47
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;
56
57 public class AboutActivity extends AppCompatActivity implements SaveDialog.SaveListener {
58     // Declare the class variables.
59     private AboutPagerAdapter aboutPagerAdapter;
60
61     @Override
62     protected void onCreate(Bundle savedInstanceState) {
63         // Get a handle for the shared preferences.
64         SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
65
66         // Get the screenshot preference.
67         boolean allowScreenshots = sharedPreferences.getBoolean("allow_screenshots", false);
68
69         // Disable screenshots if not allowed.
70         if (!allowScreenshots) {
71             getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE);
72         }
73
74         // Set the theme.
75         setTheme(R.style.PrivacyBrowser);
76
77         // Run the default commands.
78         super.onCreate(savedInstanceState);
79
80         // Get the intent that launched the activity.
81         Intent launchingIntent = getIntent();
82
83         // Store the blocklist versions.
84         String[] blocklistVersions = launchingIntent.getStringArrayExtra("blocklist_versions");
85
86         // Remove the incorrect lint warning below that the blocklist versions might be null.
87         assert blocklistVersions != null;
88
89         // Set the content view.
90         setContentView(R.layout.about_coordinatorlayout);
91
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);
96
97         // Set the action bar.  `SupportActionBar` must be used until the minimum API is >= 21.
98         setSupportActionBar(toolbar);
99
100         // Get a handle for the action bar.
101         final ActionBar actionBar = getSupportActionBar();
102
103         // Remove the incorrect lint warning that the action bar might be null.
104         assert actionBar != null;  //
105
106         // Display the home arrow on action bar.
107         actionBar.setDisplayHomeAsUpEnabled(true);
108
109         // Initialize the about pager adapter.
110         aboutPagerAdapter = new AboutPagerAdapter(getSupportFragmentManager(), getApplicationContext(), blocklistVersions);
111
112         // Setup the ViewPager.
113         aboutViewPager.setAdapter(aboutPagerAdapter);
114
115         // Keep all the tabs in memory.  This prevents the memory usage updater from running multiple times.
116         aboutViewPager.setOffscreenPageLimit(10);
117
118         // Connect the tab layout to the view pager.
119         aboutTabLayout.setupWithViewPager(aboutViewPager);
120     }
121
122     // The activity result is called after browsing for a file in the save alert dialog.
123     @Override
124     public void onActivityResult(int requestCode, int resultCode, Intent returnedIntent) {
125         // Run the default commands.
126         super.onActivityResult(requestCode, resultCode, returnedIntent);
127
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));
132
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();
137
138                 // Remove the lint warning below that the dialog might be null.
139                 assert saveDialog != null;
140
141                 // Get a handle for the dialog view.
142                 EditText fileNameEditText = saveDialog.findViewById(R.id.file_name_edittext);
143
144                 // Get the file name URI from the intent.
145                 Uri fileNameUri = returnedIntent.getData();
146
147                 // Get the file name string from the URI.
148                 String fileNameString = fileNameUri.toString();
149
150                 // Set the file name text.
151                 fileNameEditText.setText(fileNameString);
152
153                 // Move the cursor to the end of the file name edit text.
154                 fileNameEditText.setSelection(fileNameString.length());
155             }
156         }
157     }
158
159     @Override
160     public void onSave(int saveType, DialogFragment dialogFragment) {
161         // Get a handle for the dialog.
162         Dialog dialog = dialogFragment.getDialog();
163
164         // Remove the lint warning below that the dialog might be null.
165         assert dialog != null;
166
167         // Get a handle for the file name edit text.
168         EditText fileNameEditText = dialog.findViewById(R.id.file_name_edittext);
169
170         // Get the file name string.
171         String fileNameString = fileNameEditText.getText().toString();
172
173         // Get a handle for the about version linear layout.
174         LinearLayout aboutVersionLinearLayout = findViewById(R.id.about_version_linearlayout);
175
176         // Save the file according to the type.
177         switch (saveType) {
178             case SaveDialog.SAVE_ABOUT_VERSION_TEXT:
179                 try {
180                     // Get a handle for the about version fragment.
181                     AboutVersionFragment aboutVersionFragment = (AboutVersionFragment) aboutPagerAdapter.getTabFragment(0);
182
183                     // Get the about version text.
184                     String aboutVersionString = aboutVersionFragment.getAboutVersionString();
185
186                     // Create an input stream with the contents of about version.
187                     InputStream aboutVersionInputStream = new ByteArrayInputStream(aboutVersionString.getBytes(StandardCharsets.UTF_8));
188
189                     // Create an about version buffered reader.
190                     BufferedReader aboutVersionBufferedReader = new BufferedReader(new InputStreamReader(aboutVersionInputStream));
191
192                     // Open an output stream.
193                     OutputStream outputStream = getContentResolver().openOutputStream(Uri.parse(fileNameString));
194
195                     // Create a file buffered writer.
196                     BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream));
197
198                     // Create a transfer string.
199                     String transferString;
200
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);
205
206                         // Append a line break.
207                         bufferedWriter.append("\n");
208                     }
209
210                     // Flush the buffered writer.
211                     bufferedWriter.flush();
212
213                     // Close the inputs and outputs.
214                     aboutVersionBufferedReader.close();
215                     aboutVersionInputStream.close();
216                     bufferedWriter.close();
217                     outputStream.close();
218
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();
224                 }
225                 break;
226
227             case SaveDialog.SAVE_ABOUT_VERSION_IMAGE:
228                 // Save the about version image.
229                 new SaveAboutVersionImage(this, fileNameString, aboutVersionLinearLayout).execute();
230                 break;
231         }
232     }
233 }