X-Git-Url: https://gitweb.stoutner.com/?p=PrivacyBrowserAndroid.git;a=blobdiff_plain;f=app%2Fsrc%2Fmain%2Fjava%2Fcom%2Fstoutner%2Fprivacybrowser%2Factivities%2FImportExportActivity.java;h=4c48b42631d560c606e53e655861b028a27d0532;hp=de4ec4779fb45350bbb5a971260a376fa07acdb8;hb=59c4102ba387c8a4104923eba9c90124c3e9e481;hpb=d4f39c36beb5e6c3568a1e075274ad66defd8e8e diff --git a/app/src/main/java/com/stoutner/privacybrowser/activities/ImportExportActivity.java b/app/src/main/java/com/stoutner/privacybrowser/activities/ImportExportActivity.java index de4ec477..4c48b426 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/activities/ImportExportActivity.java +++ b/app/src/main/java/com/stoutner/privacybrowser/activities/ImportExportActivity.java @@ -1,20 +1,20 @@ /* - * Copyright © 2018-2021 Soren Stoutner . + * Copyright 2018-2022 Soren Stoutner . * - * This file is part of Privacy Browser . + * This file is part of Privacy Browser Android . * - * Privacy Browser is free software: you can redistribute it and/or modify + * Privacy Browser Android is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Privacy Browser is distributed in the hope that it will be useful, + * Privacy Browser Android is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Privacy Browser. If not, see . + * along with Privacy Browser Android. If not, see . */ package com.stoutner.privacybrowser.activities; @@ -24,7 +24,6 @@ import android.content.Intent; import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.net.Uri; -import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.preference.PreferenceManager; @@ -47,11 +46,11 @@ import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.widget.Toolbar; import androidx.cardview.widget.CardView; import androidx.core.content.FileProvider; -import androidx.multidex.BuildConfig; import com.google.android.material.snackbar.Snackbar; import com.google.android.material.textfield.TextInputLayout; +import com.stoutner.privacybrowser.BuildConfig; import com.stoutner.privacybrowser.R; import com.stoutner.privacybrowser.helpers.ImportExportDatabaseHelper; @@ -85,7 +84,6 @@ public class ImportExportActivity extends AppCompatActivity { // Define the saved instance state constants. private final String ENCRYPTION_PASSWORD_TEXTINPUTLAYOUT_VISIBILITY = "encryption_password_textinputlayout_visibility"; - private final String KITKAT_PASSWORD_ENCRYPTED_TEXTVIEW_VISIBILITY = "kitkat_password_encrypted_textview_visibility"; private final String OPEN_KEYCHAIN_REQUIRED_TEXTVIEW_VISIBILITY = "open_keychain_required_textview_visibility"; private final String FILE_LOCATION_CARD_VIEW = "file_location_card_view"; private final String FILE_NAME_LINEARLAYOUT_VISIBILITY = "file_name_linearlayout_visibility"; @@ -98,7 +96,6 @@ public class ImportExportActivity extends AppCompatActivity { Spinner encryptionSpinner; TextInputLayout encryptionPasswordTextInputLayout; EditText encryptionPasswordEditText; - TextView kitKatPasswordEncryptionTextView; TextView openKeychainRequiredTextView; CardView fileLocationCardView; RadioButton importRadioButton; @@ -108,6 +105,7 @@ public class ImportExportActivity extends AppCompatActivity { Button importExportButton; // Define the class variables. + private File fileProviderDirectory; private boolean openKeychainInstalled; private File temporaryPgpEncryptedImportFile; private File temporaryPreEncryptedExportFile; @@ -117,25 +115,29 @@ public class ImportExportActivity extends AppCompatActivity { // Get a handle for the shared preferences. SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this); - // Get the screenshot preference. - boolean allowScreenshots = sharedPreferences.getBoolean("allow_screenshots", false); + // Get the preferences. + boolean allowScreenshots = sharedPreferences.getBoolean(getString(R.string.allow_screenshots_key), false); + boolean bottomAppBar = sharedPreferences.getBoolean(getString(R.string.bottom_app_bar_key), false); // Disable screenshots if not allowed. if (!allowScreenshots) { getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE); } - // Set the theme. - setTheme(R.style.PrivacyBrowser); - // Run the default commands. super.onCreate(savedInstanceState); // Set the content view. - setContentView(R.layout.import_export_coordinatorlayout); + if (bottomAppBar) { + setContentView(R.layout.import_export_bottom_appbar); + } else { + setContentView(R.layout.import_export_top_appbar); + } - // Set the support action bar. + // Get a handle for the toolbar. Toolbar toolbar = findViewById(R.id.import_export_toolbar); + + // Set the support action bar. setSupportActionBar(toolbar); // Get a handle for the action bar. @@ -147,9 +149,6 @@ public class ImportExportActivity extends AppCompatActivity { // Display the home arrow on the support action bar. actionBar.setDisplayHomeAsUpEnabled(true); - // Find out if the system is running KitKat - boolean runningKitKat = (Build.VERSION.SDK_INT == 19); - // Find out if OpenKeychain is installed. try { openKeychainInstalled = !getPackageManager().getPackageInfo("org.sufficientlysecure.keychain", 0).versionName.isEmpty(); @@ -161,7 +160,6 @@ public class ImportExportActivity extends AppCompatActivity { encryptionSpinner = findViewById(R.id.encryption_spinner); encryptionPasswordTextInputLayout = findViewById(R.id.encryption_password_textinputlayout); encryptionPasswordEditText = findViewById(R.id.encryption_password_edittext); - kitKatPasswordEncryptionTextView = findViewById(R.id.kitkat_password_encryption_textview); openKeychainRequiredTextView = findViewById(R.id.openkeychain_required_textview); fileLocationCardView = findViewById(R.id.file_location_cardview); importRadioButton = findViewById(R.id.import_radiobutton); @@ -188,7 +186,6 @@ public class ImportExportActivity extends AppCompatActivity { case NO_ENCRYPTION: // Hide the unneeded layout items. encryptionPasswordTextInputLayout.setVisibility(View.GONE); - kitKatPasswordEncryptionTextView.setVisibility(View.GONE); openKeychainRequiredTextView.setVisibility(View.GONE); openKeychainImportInstructionsTextView.setVisibility(View.GONE); @@ -210,43 +207,33 @@ public class ImportExportActivity extends AppCompatActivity { break; case PASSWORD_ENCRYPTION: - if (runningKitKat) { - // Show the KitKat password encryption message. - kitKatPasswordEncryptionTextView.setVisibility(View.VISIBLE); - - // Hide the OpenPGP required text view and the file location card. - openKeychainRequiredTextView.setVisibility(View.GONE); - fileLocationCardView.setVisibility(View.GONE); - } else { - // Hide the OpenPGP layout items. - openKeychainRequiredTextView.setVisibility(View.GONE); - openKeychainImportInstructionsTextView.setVisibility(View.GONE); - - // Show the password encryption layout items. - encryptionPasswordTextInputLayout.setVisibility(View.VISIBLE); + // Hide the OpenPGP layout items. + openKeychainRequiredTextView.setVisibility(View.GONE); + openKeychainImportInstructionsTextView.setVisibility(View.GONE); - // Show the file location card. - fileLocationCardView.setVisibility(View.VISIBLE); + // Show the password encryption layout items. + encryptionPasswordTextInputLayout.setVisibility(View.VISIBLE); - // Show the file name linear layout if either import or export is checked. - if (importRadioButton.isChecked() || exportRadioButton.isChecked()) { - fileNameLinearLayout.setVisibility(View.VISIBLE); - } + // Show the file location card. + fileLocationCardView.setVisibility(View.VISIBLE); - // Reset the text of the import button, which may have been changed to `Decrypt`. - if (importRadioButton.isChecked()) { - importExportButton.setText(R.string.import_button); - } + // Show the file name linear layout if either import or export is checked. + if (importRadioButton.isChecked() || exportRadioButton.isChecked()) { + fileNameLinearLayout.setVisibility(View.VISIBLE); + } - // Enable the import/button if both the password and the file name are populated. - importExportButton.setEnabled(!fileNameEditText.getText().toString().isEmpty() && !encryptionPasswordEditText.getText().toString().isEmpty()); + // Reset the text of the import button, which may have been changed to `Decrypt`. + if (importRadioButton.isChecked()) { + importExportButton.setText(R.string.import_button); } + + // Enable the import/button if both the password and the file name are populated. + importExportButton.setEnabled(!fileNameEditText.getText().toString().isEmpty() && !encryptionPasswordEditText.getText().toString().isEmpty()); break; case OPENPGP_ENCRYPTION: // Hide the password encryption layout items. encryptionPasswordTextInputLayout.setVisibility(View.GONE); - kitKatPasswordEncryptionTextView.setVisibility(View.GONE); // Updated items based on the installation status of OpenKeychain. if (openKeychainInstalled) { // OpenKeychain is installed. @@ -336,7 +323,6 @@ public class ImportExportActivity extends AppCompatActivity { if (savedInstanceState == null) { // The app has not been restarted. // Initially hide the unneeded views. encryptionPasswordTextInputLayout.setVisibility(View.GONE); - kitKatPasswordEncryptionTextView.setVisibility(View.GONE); openKeychainRequiredTextView.setVisibility(View.GONE); fileNameLinearLayout.setVisibility(View.GONE); openKeychainImportInstructionsTextView.setVisibility(View.GONE); @@ -344,7 +330,6 @@ public class ImportExportActivity extends AppCompatActivity { } else { // The app has been restarted. // Restore the visibility of the views. encryptionPasswordTextInputLayout.setVisibility(savedInstanceState.getInt(ENCRYPTION_PASSWORD_TEXTINPUTLAYOUT_VISIBILITY)); - kitKatPasswordEncryptionTextView.setVisibility(savedInstanceState.getInt(KITKAT_PASSWORD_ENCRYPTED_TEXTVIEW_VISIBILITY)); openKeychainRequiredTextView.setVisibility(savedInstanceState.getInt(OPEN_KEYCHAIN_REQUIRED_TEXTVIEW_VISIBILITY)); fileLocationCardView.setVisibility(savedInstanceState.getInt(FILE_LOCATION_CARD_VIEW)); fileNameLinearLayout.setVisibility(savedInstanceState.getInt(FILE_NAME_LINEARLAYOUT_VISIBILITY)); @@ -364,7 +349,6 @@ public class ImportExportActivity extends AppCompatActivity { // Save the visibility of the views. savedInstanceState.putInt(ENCRYPTION_PASSWORD_TEXTINPUTLAYOUT_VISIBILITY, encryptionPasswordTextInputLayout.getVisibility()); - savedInstanceState.putInt(KITKAT_PASSWORD_ENCRYPTED_TEXTVIEW_VISIBILITY, kitKatPasswordEncryptionTextView.getVisibility()); savedInstanceState.putInt(OPEN_KEYCHAIN_REQUIRED_TEXTVIEW_VISIBILITY, openKeychainRequiredTextView.getVisibility()); savedInstanceState.putInt(FILE_LOCATION_CARD_VIEW, fileLocationCardView.getVisibility()); savedInstanceState.putInt(FILE_NAME_LINEARLAYOUT_VISIBILITY, fileNameLinearLayout.getVisibility()); @@ -516,6 +500,13 @@ public class ImportExportActivity extends AppCompatActivity { //noinspection ResultOfMethodCallIgnored temporaryPgpEncryptedImportFile.delete(); } + + // Delete the file provider directory if it exists. + if (fileProviderDirectory.exists()) { + //noinspection ResultOfMethodCallIgnored + fileProviderDirectory.delete(); + } + break; case OPENPGP_EXPORT_RESULT_CODE: @@ -524,6 +515,13 @@ public class ImportExportActivity extends AppCompatActivity { //noinspection ResultOfMethodCallIgnored temporaryPreEncryptedExportFile.delete(); } + + // Delete the file provider directory if it exists. + if (fileProviderDirectory.exists()) { + //noinspection ResultOfMethodCallIgnored + fileProviderDirectory.delete(); + } + break; } } @@ -545,6 +543,7 @@ public class ImportExportActivity extends AppCompatActivity { case NO_ENCRYPTION: try { // Get an input stream for the file name. + // A file may be opened directly once the minimum API >= 29. InputStream inputStream = getContentResolver().openInputStream(Uri.parse(fileNameString)); // Import the unencrypted file. @@ -673,8 +672,15 @@ public class ImportExportActivity extends AppCompatActivity { case OPENPGP_ENCRYPTION: try { + // Get a handle for the file provider directory. + fileProviderDirectory = new File(getApplicationContext().getCacheDir() + "/" + getString(R.string.file_provider_directory)); + + // Create the file provider directory. Any errors will be handled by the catch statement below. + //noinspection ResultOfMethodCallIgnored + fileProviderDirectory.mkdir(); + // Set the temporary PGP encrypted import file. - temporaryPgpEncryptedImportFile = File.createTempFile("temporary_pgp_encrypted_import_file", null, getApplicationContext().getCacheDir()); + temporaryPgpEncryptedImportFile = File.createTempFile("temporary_pgp_encrypted_import_file", null, fileProviderDirectory); // Create a temporary PGP encrypted import file output stream. FileOutputStream temporaryPgpEncryptedImportFileOutputStream = new FileOutputStream(temporaryPgpEncryptedImportFile); @@ -698,8 +704,7 @@ public class ImportExportActivity extends AppCompatActivity { // Close the streams. inputStream.close(); - temporaryPgpEncryptedImportFileOutputStream.flush(); - + temporaryPgpEncryptedImportFileOutputStream.close(); // Create an decryption intent for OpenKeychain. Intent openKeychainDecryptIntent = new Intent("org.sufficientlysecure.keychain.action.DECRYPT_DATA"); @@ -739,6 +744,7 @@ public class ImportExportActivity extends AppCompatActivity { try { // Get the export file output stream. + // A file may be opened directly once the minimum API >= 29. OutputStream exportFileOutputStream = getContentResolver().openOutputStream(Uri.parse(noEncryptionFileNameString)); // Export the unencrypted file. @@ -874,8 +880,15 @@ public class ImportExportActivity extends AppCompatActivity { case OPENPGP_ENCRYPTION: try { + // Get a handle for the file provider directory. + fileProviderDirectory = new File(getApplicationContext().getCacheDir() + "/" + getString(R.string.file_provider_directory)); + + // Create the file provider directory. Any errors will be handled by the catch statement below. + //noinspection ResultOfMethodCallIgnored + fileProviderDirectory.mkdir(); + // Set the temporary pre-encrypted export file. - temporaryPreEncryptedExportFile = new File(getApplicationContext().getCacheDir() + "/" + getString(R.string.settings) + " " + BuildConfig.VERSION_NAME + ".pbs"); + temporaryPreEncryptedExportFile = new File(fileProviderDirectory + "/" + getString(R.string.settings) + " " + BuildConfig.VERSION_NAME + ".pbs"); // Delete the temporary pre-encrypted export file if it already exists. if (temporaryPreEncryptedExportFile.exists()) { @@ -948,4 +961,4 @@ public class ImportExportActivity extends AppCompatActivity { // Restart Privacy Browser after 150 milliseconds to allow enough time for the preferences to be saved. restartHandler.postDelayed(restartRunnable, 150); } -} \ No newline at end of file +}