X-Git-Url: https://gitweb.stoutner.com/?p=PrivacyBrowserAndroid.git;a=blobdiff_plain;f=app%2Fsrc%2Fmain%2Fjava%2Fcom%2Fstoutner%2Fprivacybrowser%2Factivities%2FMainWebViewActivity.java;h=9f51f749dcbb26993e1eb87fcb1b4cd3b383cc24;hp=eff9c68d0f1820ccc59e7ad069394a44a38e32b9;hb=86e63c8ed007311ab392d4beb7dd7ba64b9c3c70;hpb=b870c254c26d19749fef9e3dbe9894f8f40c32eb diff --git a/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java b/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java index eff9c68d..9f51f749 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java +++ b/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java @@ -148,7 +148,6 @@ import com.stoutner.privacybrowser.fragments.WebViewTabFragment; import com.stoutner.privacybrowser.helpers.AdHelper; import com.stoutner.privacybrowser.helpers.BlocklistHelper; import com.stoutner.privacybrowser.helpers.BookmarksDatabaseHelper; -import com.stoutner.privacybrowser.helpers.CheckPinnedMismatchHelper; import com.stoutner.privacybrowser.helpers.DomainsDatabaseHelper; import com.stoutner.privacybrowser.helpers.FileNameHelper; import com.stoutner.privacybrowser.helpers.ProxyHelper; @@ -189,10 +188,6 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // The WebView pager adapter is accessed from `HttpAuthenticationDialog`, `PinnedMismatchDialog`, and `SslCertificateErrorDialog`. It is also used in `onCreate()`, `onResume()`, and `addTab()`. public static WebViewPagerAdapter webViewPagerAdapter; - // The load URL on restart variables are public static so they can be accessed from `BookmarksActivity`. They are used in `onRestart()`. - public static boolean loadUrlOnRestart; - public static String urlToLoadOnRestart; - // `restartFromBookmarksActivity` is public static so it can be accessed from `BookmarksActivity`. It is also used in `onRestart()`. public static boolean restartFromBookmarksActivity; @@ -550,21 +545,12 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Reapply the domain settings if the URL is not null, which can happen if an empty tab is active when returning from settings. if (nestedScrollWebView.getUrl() != null) { - applyDomainSettings(nestedScrollWebView, nestedScrollWebView.getUrl(), false, true); + applyDomainSettings(nestedScrollWebView, nestedScrollWebView.getUrl(), false, true, false); } } } } - // Load the URL on restart (used when loading a bookmark). - if (loadUrlOnRestart) { - // Load the specified URL. - loadUrl(currentWebView, urlToLoadOnRestart); - - // Reset the load on restart tracker. - loadUrlOnRestart = false; - } - // Update the bookmarks drawer if returning from the Bookmarks activity. if (restartFromBookmarksActivity) { // Close the bookmarks drawer. @@ -1955,7 +1941,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook String previousUrl = webBackForwardList.getItemAtIndex(webBackForwardList.getCurrentIndex() - 1).getUrl(); // Apply the domain settings. - applyDomainSettings(currentWebView, previousUrl, false, false); + applyDomainSettings(currentWebView, previousUrl, false, false, false); // Load the previous website in the history. currentWebView.goBack(); @@ -1971,7 +1957,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook String nextUrl = webBackForwardList.getItemAtIndex(webBackForwardList.getCurrentIndex() + 1).getUrl(); // Apply the domain settings. - applyDomainSettings(currentWebView, nextUrl, false, false); + applyDomainSettings(currentWebView, nextUrl, false, false, false); // Load the next website in the history. currentWebView.goForward(); @@ -2143,7 +2129,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook @Override public void onCreateContextMenu(ContextMenu menu, View view, ContextMenu.ContextMenuInfo menuInfo) { - // Store the hit test result. + // Get the hit test result. final WebView.HitTestResult hitTestResult = currentWebView.getHitTestResult(); // Define the URL strings. @@ -2231,8 +2217,17 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Get the image URL. imageUrl = hitTestResult.getExtra(); - // Set the image URL as the title of the context menu. - menu.setHeaderTitle(imageUrl); + // Remove the incorrect lint warning below that the image URL might be null. + assert imageUrl != null; + + // Set the context menu title. + if (imageUrl.startsWith("data:")) { // The image data is contained in within the URL, making it exceedingly long. + // Truncate the image URL before making it the title. + menu.setHeaderTitle(imageUrl.substring(0, 100)); + } else { // The image URL does not contain the full image data. + // Set the image URL as the title of the context menu. + menu.setHeaderTitle(imageUrl); + } // Add an Open in New Tab entry. menu.add(R.string.open_image_in_new_tab).setOnMenuItemClickListener((MenuItem item) -> { @@ -2724,7 +2719,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook String previousUrl = webBackForwardList.getItemAtIndex(webBackForwardList.getCurrentIndex() - 1).getUrl(); // Apply the domain settings. - applyDomainSettings(currentWebView, previousUrl, false, false); + applyDomainSettings(currentWebView, previousUrl, false, false, false); // Go back. currentWebView.goBack(); @@ -2910,11 +2905,8 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Sanitize the URL. url = sanitizeUrl(url); - // Apply the domain settings. - applyDomainSettings(nestedScrollWebView, url, true, false); - - // Load the URL. - nestedScrollWebView.loadUrl(url, customHeaders); + // Apply the domain settings and load the URL. + applyDomainSettings(nestedScrollWebView, url, true, false, true); } public void findPreviousOnPage(View view) { @@ -2996,6 +2988,9 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Get the file path string. openFilePath = fileNameEditText.getText().toString(); + // Apply the domain settings. This resets the favorite icon and removes any domain settings. + applyDomainSettings(currentWebView, "file://" + openFilePath, true, false, false); + // Check to see if the storage permission is needed. if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) { // The storage permission has been granted. // Open the file. @@ -3031,7 +3026,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook } @Override - public void onSaveWebpage(int saveType, DialogFragment dialogFragment) { + public void onSaveWebpage(int saveType, String originalUrlString, DialogFragment dialogFragment) { // Get the dialog. Dialog dialog = dialogFragment.getDialog(); @@ -3042,8 +3037,16 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook EditText urlEditText = dialog.findViewById(R.id.url_edittext); EditText fileNameEditText = dialog.findViewById(R.id.file_name_edittext); - // Get the strings from the edit texts. - saveWebpageUrl = urlEditText.getText().toString(); + // Store the URL. + if ((originalUrlString != null) && originalUrlString.startsWith("data:")) { + // Save the original URL. + saveWebpageUrl = originalUrlString; + } else { + // Get the URL from the edit text, which may have been modified. + saveWebpageUrl = urlEditText.getText().toString(); + } + + // Get the file path from the edit text. saveWebpageFilePath = fileNameEditText.getText().toString(); // Check to see if the storage permission is needed. @@ -3057,7 +3060,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook case StoragePermissionDialog.SAVE_ARCHIVE: // Save the webpage archive. - saveWebpageArchive(); + saveWebpageArchive(saveWebpageFilePath); break; case StoragePermissionDialog.SAVE_IMAGE: @@ -3065,6 +3068,10 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook new SaveWebpageImage(this, this, saveWebpageFilePath, currentWebView).execute(); break; } + + // Reset the strings. + saveWebpageUrl = ""; + saveWebpageFilePath = ""; } else { // The storage permission has not been granted. // Get the external private directory file. File externalPrivateDirectoryFile = getExternalFilesDir(null); @@ -3086,7 +3093,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook case StoragePermissionDialog.SAVE_ARCHIVE: // Save the webpage archive. - saveWebpageArchive(); + saveWebpageArchive(saveWebpageFilePath); break; case StoragePermissionDialog.SAVE_IMAGE: @@ -3094,6 +3101,10 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook new SaveWebpageImage(this, this, saveWebpageFilePath, currentWebView).execute(); break; } + + // Reset the strings. + saveWebpageUrl = ""; + saveWebpageFilePath = ""; } else { // The file path is in a public directory. // Check if the user has previously denied the storage permission. if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) { // Show a dialog explaining the request first. @@ -3131,9 +3142,6 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Display an error snackbar. Snackbar.make(currentWebView, getString(R.string.cannot_use_location), Snackbar.LENGTH_LONG).show(); } - - // Reset the open file path. - openFilePath = ""; break; case StoragePermissionDialog.SAVE_URL: @@ -3145,24 +3153,17 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Display an error snackbar. Snackbar.make(currentWebView, getString(R.string.cannot_use_location), Snackbar.LENGTH_LONG).show(); } - - // Reset the save strings. - saveWebpageUrl = ""; - saveWebpageFilePath = ""; break; case StoragePermissionDialog.SAVE_ARCHIVE: // Check to see if the storage permission was granted. If the dialog was canceled the grant results will be empty. if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { // The storage permission was granted. // Save the webpage archive. - saveWebpageArchive(); + saveWebpageArchive(saveWebpageFilePath); } else { // The storage permission was not granted. // Display an error snackbar. Snackbar.make(currentWebView, getString(R.string.cannot_use_location), Snackbar.LENGTH_LONG).show(); } - - // Reset the save webpage file path. - saveWebpageFilePath = ""; break; case StoragePermissionDialog.SAVE_IMAGE: @@ -3174,11 +3175,13 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Display an error snackbar. Snackbar.make(currentWebView, getString(R.string.cannot_use_location), Snackbar.LENGTH_LONG).show(); } - - // Reset the save webpage file path. - saveWebpageFilePath = ""; break; } + + // Reset the strings. + openFilePath = ""; + saveWebpageUrl = ""; + saveWebpageFilePath = ""; } } @@ -3329,11 +3332,8 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Select the corresponding tab if it does not match the currently selected page. This will happen if the page was scrolled by creating a new tab. if (tabLayout.getSelectedTabPosition() != position) { - // Create a handler to select the tab. - Handler selectTabHandler = new Handler(); - - // Create a runnable to select the tab. - Runnable selectTabRunnable = () -> { + // Wait until the new tab has been created. + tabLayout.post(() -> { // Get a handle for the tab. TabLayout.Tab tab = tabLayout.getTabAt(position); @@ -3342,10 +3342,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Select the tab. tab.select(); - }; - - // Select the tab layout after 150 milliseconds, which leaves enough time for a new tab to be inflated. TODO. - selectTabHandler.postDelayed(selectTabRunnable, 150); + }); } } @@ -3768,7 +3765,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook @Override public void navigateHistory(String url, int steps) { // Apply the domain settings. - applyDomainSettings(currentWebView, url, false, false); + applyDomainSettings(currentWebView, url, false, false, false); // Load the history entry. currentWebView.goBackOrForward(steps); @@ -3783,7 +3780,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook String previousUrl = webBackForwardList.getItemAtIndex(webBackForwardList.getCurrentIndex() - 1).getUrl(); // Apply the domain settings. - applyDomainSettings(currentWebView, previousUrl, false, false); + applyDomainSettings(currentWebView, previousUrl, false, false, false); // Go back. currentWebView.goBack(); @@ -3791,7 +3788,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // `reloadWebsite` is used if returning from the Domains activity. Otherwise JavaScript might not function correctly if it is newly enabled. @SuppressLint("SetJavaScriptEnabled") - private void applyDomainSettings(NestedScrollWebView nestedScrollWebView, String url, boolean resetTab, boolean reloadWebsite) { + private void applyDomainSettings(NestedScrollWebView nestedScrollWebView, String url, boolean resetTab, boolean reloadWebsite, boolean loadUrl) { // Store the current URL. nestedScrollWebView.setCurrentUrl(url); @@ -4310,6 +4307,11 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook if (reloadWebsite) { nestedScrollWebView.reload(); } + + // Load the URL if directed. This makes sure that the domain settings are properly loaded before the URL. By using `loadUrl()`, instead of `loadUrlFromBase()`, the Referer header will never be sent. + if (loadUrl) { + nestedScrollWebView.loadUrl(url, customHeaders); + } } private void applyProxy(boolean reloadWebViews) { @@ -4757,6 +4759,9 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Get the intent that started the app. Intent intent = getIntent(); + // Reset the intent. This prevents a duplicate tab from being created on restart. + setIntent(new Intent()); + // Get the information from the intent. String intentAction = intent.getAction(); Uri intentUriData = intent.getData(); @@ -4842,6 +4847,12 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook } private void closeCurrentTab() { + // Pause the current WebView. + currentWebView.onPause(); + + // Pause the current WebView JavaScript timers. + currentWebView.pauseTimers(); + // Get the current tab number. int currentTabNumber = tabLayout.getSelectedTabPosition(); @@ -4857,17 +4868,17 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook appBarLayout.setExpanded(true); } - private void saveWebpageArchive() { + private void saveWebpageArchive(String filePath) { // Save the webpage archive. - currentWebView.saveWebArchive(saveWebpageFilePath); + currentWebView.saveWebArchive(filePath); // Display a snackbar. - Snackbar saveWebpageArchiveSnackbar = Snackbar.make(currentWebView, getString(R.string.file_saved) + " " + saveWebpageFilePath, Snackbar.LENGTH_SHORT); + Snackbar saveWebpageArchiveSnackbar = Snackbar.make(currentWebView, getString(R.string.file_saved) + " " + filePath, Snackbar.LENGTH_SHORT); // Add an open option to the snackbar. saveWebpageArchiveSnackbar.setAction(R.string.open, (View view) -> { // Get a file for the file name string. - File file = new File(saveWebpageFilePath); + File file = new File(filePath); // Declare a file URI variable. Uri fileUri; @@ -4897,9 +4908,6 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Show the snackbar. saveWebpageArchiveSnackbar.show(); - - // Reset the save Webpage file path. - saveWebpageFilePath = ""; } private void clearAndExit() { @@ -5730,11 +5738,8 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Handle the URL according to the type. if (url.startsWith("http")) { // Load the URL in Privacy Browser. - // Apply the domain settings for the new URL. This doesn't do anything if the domain has not changed. - applyDomainSettings(nestedScrollWebView, url, true, false); - // Load the URL. By using `loadUrl()`, instead of `loadUrlFromBase()`, the Referer header will never be sent. - nestedScrollWebView.loadUrl(url, customHeaders); + loadUrl(nestedScrollWebView, url); // Returning true indicates that Privacy Browser is manually handling the loading of the URL. // Custom headers cannot be added if false is returned and the WebView handles the loading of the URL. @@ -6288,7 +6293,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook } } - // Clear the cache and history if Incognito Mode is enabled. + // Clear the cache, history, and logcat if Incognito Mode is enabled. if (incognitoModeEnabled) { // Clear the cache. `true` includes disk files. nestedScrollWebView.clearCache(true); @@ -6308,20 +6313,22 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Delete the secondary `Service Worker` cache directory. // A `String[]` must be used because the directory contains a space and `Runtime.exec` will not escape the string correctly otherwise. Runtime.getRuntime().exec(new String[]{"rm", "-rf", privateDataDirectoryString + "/app_webview/Service Worker/"}); - } catch (IOException e) { + } catch (IOException exception) { // Do nothing if an error is thrown. } + + // Clear the logcat. + try { + // Clear the logcat. `-c` clears the logcat. `-b all` clears all the buffers (instead of just crash, main, and system). + Runtime.getRuntime().exec("logcat -b all -c"); + } catch (IOException exception) { + // Do nothing. + } } // Get the current page position. int currentPagePosition = webViewPagerAdapter.getPositionForId(nestedScrollWebView.getWebViewFragmentId()); - // Check the current website information against any pinned domain information if the current IP addresses have been loaded. - if ((nestedScrollWebView.hasPinnedSslCertificate() || nestedScrollWebView.hasPinnedIpAddresses()) && nestedScrollWebView.hasCurrentIpAddresses() && - !nestedScrollWebView.ignorePinnedDomainInformation()) { - CheckPinnedMismatchHelper.checkPinnedMismatch(getSupportFragmentManager(), nestedScrollWebView); - } - // Get the current URL from the nested scroll WebView. This is more accurate than using the URL passed into the method, which is sometimes not the final one. String currentUrl = nestedScrollWebView.getUrl(); @@ -6344,7 +6351,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook inputMethodManager.showSoftInput(urlEditText, 0); // Apply the domain settings. This clears any settings from the previous domain. - applyDomainSettings(nestedScrollWebView, "", true, false); + applyDomainSettings(nestedScrollWebView, "", true, false, false); // Only populate the title text view if the tab has been fully created. if (tab != null) { @@ -6452,6 +6459,9 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Get the intent that started the app. Intent launchingIntent = getIntent(); + // Reset the intent. This prevents a duplicate tab from being created on restart. + setIntent(new Intent()); + // Get the information from the intent. String launchingIntentAction = launchingIntent.getAction(); Uri launchingIntentUriData = launchingIntent.getData();