From 3f3b7c8fbe988fe730a5fbb53169489566655595 Mon Sep 17 00:00:00 2001 From: Soren Stoutner Date: Wed, 17 Jul 2019 15:49:23 -0700 Subject: [PATCH] Fix applying domain settings when navigating history. https://redmine.stoutner.com/issues/439 --- .../activities/MainWebViewActivity.java | 82 +++++++++++++------ .../dialogs/PinnedMismatchDialog.java | 25 ++++-- .../dialogs/UrlHistoryDialog.java | 33 ++++++-- .../views/NestedScrollWebView.java | 15 ---- app/src/main/res/values-tr/strings.xml | 5 +- 5 files changed, 105 insertions(+), 55 deletions(-) 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 5f8d8075..7f91e043 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java +++ b/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java @@ -73,6 +73,7 @@ import android.webkit.CookieManager; import android.webkit.HttpAuthHandler; import android.webkit.SslErrorHandler; import android.webkit.ValueCallback; +import android.webkit.WebBackForwardList; import android.webkit.WebChromeClient; import android.webkit.WebResourceResponse; import android.webkit.WebSettings; @@ -129,6 +130,7 @@ import com.stoutner.privacybrowser.dialogs.DownloadLocationPermissionDialog; import com.stoutner.privacybrowser.dialogs.EditBookmarkDialog; import com.stoutner.privacybrowser.dialogs.EditBookmarkFolderDialog; import com.stoutner.privacybrowser.dialogs.HttpAuthenticationDialog; +import com.stoutner.privacybrowser.dialogs.PinnedMismatchDialog; import com.stoutner.privacybrowser.dialogs.SaveWebpageImageDialog; import com.stoutner.privacybrowser.dialogs.SslCertificateErrorDialog; import com.stoutner.privacybrowser.dialogs.StoragePermissionDialog; @@ -164,8 +166,8 @@ import java.util.Set; // AppCompatActivity from android.support.v7.app.AppCompatActivity must be used to have access to the SupportActionBar until the minimum API is >= 21. public class MainWebViewActivity extends AppCompatActivity implements CreateBookmarkDialog.CreateBookmarkListener, CreateBookmarkFolderDialog.CreateBookmarkFolderListener, DownloadFileDialog.DownloadFileListener, DownloadImageDialog.DownloadImageListener, DownloadLocationPermissionDialog.DownloadLocationPermissionDialogListener, EditBookmarkDialog.EditBookmarkListener, - EditBookmarkFolderDialog.EditBookmarkFolderListener, NavigationView.OnNavigationItemSelectedListener, PopulateBlocklists.PopulateBlocklistsListener, SaveWebpageImageDialog.SaveWebpageImageListener, - StoragePermissionDialog.StoragePermissionDialogListener, WebViewTabFragment.NewTabListener { + EditBookmarkFolderDialog.EditBookmarkFolderListener, NavigationView.OnNavigationItemSelectedListener, PinnedMismatchDialog.PinnedMismatchListener, PopulateBlocklists.PopulateBlocklistsListener, SaveWebpageImageDialog.SaveWebpageImageListener, + StoragePermissionDialog.StoragePermissionDialogListener, UrlHistoryDialog.NavigateHistoryListener, WebViewTabFragment.NewTabListener { // `orbotStatus` is public static so it can be accessed from `OrbotProxyHelper`. It is also used in `onCreate()`, `onResume()`, and `applyProxyThroughOrbot()`. public static String orbotStatus; @@ -1803,11 +1805,17 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook case R.id.back: if (currentWebView.canGoBack()) { + // Get the current web back forward list. + WebBackForwardList webBackForwardList = currentWebView.copyBackForwardList(); + + // Get the previous entry URL. + String previousUrl = webBackForwardList.getItemAtIndex(webBackForwardList.getCurrentIndex() - 1).getUrl(); + // Reset the current domain name so that navigation works if third-party requests are blocked. currentWebView.resetCurrentDomainName(); - // Set navigating history so that the domain settings are applied when the new URL is loaded. - currentWebView.setNavigatingHistory(true); + // Apply the domain settings. + applyDomainSettings(currentWebView, previousUrl, false, false); // Load the previous website in the history. currentWebView.goBack(); @@ -1816,11 +1824,17 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook case R.id.forward: if (currentWebView.canGoForward()) { + // Get the current web back forward list. + WebBackForwardList webBackForwardList = currentWebView.copyBackForwardList(); + + // Get the next entry URL. + String nextUrl = webBackForwardList.getItemAtIndex(webBackForwardList.getCurrentIndex() + 1).getUrl(); + // Reset the current domain name so that navigation works if third-party requests are blocked. currentWebView.resetCurrentDomainName(); - // Set navigating history so that the domain settings are applied when the new URL is loaded. - currentWebView.setNavigatingHistory(true); + // Apply the domain settings. + applyDomainSettings(currentWebView, nextUrl, false, false); // Load the next website in the history. currentWebView.goForward(); @@ -2748,7 +2762,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook } } - // Override `onBackPressed` to handle the navigation drawer and and the WebView. + // Override `onBackPressed` to handle the navigation drawer and and the WebViews. @Override public void onBackPressed() { // Get a handle for the drawer layout and the tab layout. @@ -2770,11 +2784,17 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook loadBookmarksFolder(); } } else if (currentWebView.canGoBack()) { // There is at least one item in the current WebView history. + // Get the current web back forward list. + WebBackForwardList webBackForwardList = currentWebView.copyBackForwardList(); + + // Get the previous entry URL. + String previousUrl = webBackForwardList.getItemAtIndex(webBackForwardList.getCurrentIndex() - 1).getUrl(); + // Reset the current domain name so that navigation works if third-party requests are blocked. currentWebView.resetCurrentDomainName(); - // Set navigating history so that the domain settings are applied when the new URL is loaded. - currentWebView.setNavigatingHistory(true); + // Apply the domain settings. + applyDomainSettings(currentWebView, previousUrl, false, false); // Go back. currentWebView.goBack(); @@ -3594,6 +3614,36 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook bareWebView.destroy(); } + @Override + public void navigateHistory(String url, int steps) { + // Reset the current domain name so that navigation works if third-party requests are blocked. + currentWebView.resetCurrentDomainName(); + + // Apply the domain settings. + applyDomainSettings(currentWebView, url, false, false); + + // Load the history entry. + currentWebView.goBackOrForward(steps); + } + + @Override + public void pinnedErrorGoBack() { + // Get the current web back forward list. + WebBackForwardList webBackForwardList = currentWebView.copyBackForwardList(); + + // Get the previous entry URL. + String previousUrl = webBackForwardList.getItemAtIndex(webBackForwardList.getCurrentIndex() - 1).getUrl(); + + // Reset the current domain name so that navigation works if third-party requests are blocked. + currentWebView.resetCurrentDomainName(); + + // Apply the domain settings. + applyDomainSettings(currentWebView, previousUrl, false, false); + + // Go back. + currentWebView.goBack(); + } + // `reloadWebsite` is used if returning from the Domains activity. Otherwise JavaScript might not function correctly if it is newly enabled. @SuppressLint("SetJavaScriptEnabled") private boolean applyDomainSettings(NestedScrollWebView nestedScrollWebView, String url, boolean resetTab, boolean reloadWebsite) { @@ -5801,20 +5851,6 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Get the IP addresses for the host. new GetHostIpAddresses(activity, getSupportFragmentManager(), nestedScrollWebView).execute(currentUri.getHost()); - // Apply any custom domain settings if the URL was loaded by navigating history. - if (nestedScrollWebView.getNavigatingHistory()) { - // Reset navigating history. - nestedScrollWebView.setNavigatingHistory(false); - - // Apply the domain settings. - boolean userAgentChanged = applyDomainSettings(nestedScrollWebView, url, true, false); - - // Manually load the URL if the user agent has changed, which will have caused the previous URL to be reloaded. - if (userAgentChanged) { - loadUrl(url); - } - } - // Replace Refresh with Stop if the options menu has been created. (The first WebView typically begins loading before the menu items are instantiated.) if (optionsMenu != null) { // Get a handle for the refresh menu item. diff --git a/app/src/main/java/com/stoutner/privacybrowser/dialogs/PinnedMismatchDialog.java b/app/src/main/java/com/stoutner/privacybrowser/dialogs/PinnedMismatchDialog.java index 72fc85ae..9694c0ac 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/dialogs/PinnedMismatchDialog.java +++ b/app/src/main/java/com/stoutner/privacybrowser/dialogs/PinnedMismatchDialog.java @@ -59,7 +59,13 @@ import androidx.fragment.app.DialogFragment; // The AndroidX dialog fragment mu import androidx.viewpager.widget.PagerAdapter; public class PinnedMismatchDialog extends DialogFragment { + // The public interface is used to send information back to the parent activity. + public interface PinnedMismatchListener { + void pinnedErrorGoBack(); + } + // Declare the class variables. + private PinnedMismatchListener pinnedMismatchListener; private NestedScrollWebView nestedScrollWebView; private String currentSslIssuedToCName; private String currentSslIssuedToOName; @@ -70,6 +76,15 @@ public class PinnedMismatchDialog extends DialogFragment { private Date currentSslStartDate; private Date currentSslEndDate; + @Override + public void onAttach(Context context) { + // Run the default commands. + super.onAttach(context); + + // Get a handle for the listener from the launching context. + pinnedMismatchListener = (PinnedMismatchListener) context; + } + public static PinnedMismatchDialog displayDialog(long webViewFragmentId) { // Create an arguments bundle. Bundle argumentsBundle = new Bundle(); @@ -211,14 +226,8 @@ public class PinnedMismatchDialog extends DialogFragment { // Setup the back button. dialogBuilder.setNegativeButton(R.string.back, (DialogInterface dialog, int which) -> { if (nestedScrollWebView.canGoBack()) { // There is a back page in the history. - // Reset the current domain name so that navigation works if third-party requests are blocked. - nestedScrollWebView.resetCurrentDomainName(); - - // Set navigating history so that the domain settings are applied when the new URL is loaded. - nestedScrollWebView.setNavigatingHistory(true); - - // Go back. - nestedScrollWebView.goBack(); + // Invoke the navigate history listener in the calling activity. These commands cannot be run here because they need access to `applyDomainSettings()`. + pinnedMismatchListener.pinnedErrorGoBack(); } else { // There are no pages to go back to. // Load a blank page nestedScrollWebView.loadUrl(""); diff --git a/app/src/main/java/com/stoutner/privacybrowser/dialogs/UrlHistoryDialog.java b/app/src/main/java/com/stoutner/privacybrowser/dialogs/UrlHistoryDialog.java index 366566f7..8aba719b 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/dialogs/UrlHistoryDialog.java +++ b/app/src/main/java/com/stoutner/privacybrowser/dialogs/UrlHistoryDialog.java @@ -22,6 +22,7 @@ package com.stoutner.privacybrowser.dialogs; import android.annotation.SuppressLint; import android.app.AlertDialog; import android.app.Dialog; +import android.content.Context; import android.content.DialogInterface; import android.content.SharedPreferences; import android.graphics.Bitmap; @@ -35,6 +36,7 @@ import android.view.WindowManager; import android.webkit.WebBackForwardList; import android.widget.AdapterView; import android.widget.ListView; +import android.widget.TextView; import androidx.annotation.NonNull; import androidx.core.content.ContextCompat; @@ -50,6 +52,23 @@ import com.stoutner.privacybrowser.views.NestedScrollWebView; import java.util.ArrayList; public class UrlHistoryDialog extends DialogFragment{ + // The public interface is used to send information back to the parent activity. + public interface NavigateHistoryListener { + void navigateHistory(String url, int steps); + } + + // The navigate history listener is used in `onAttach()` and `onCreateDialog()`. + private NavigateHistoryListener navigateHistoryListener; + + @Override + public void onAttach(Context context) { + // Run the default commands. + super.onAttach(context); + + // Get a handle for the listener from the launching context. + navigateHistoryListener = (NavigateHistoryListener) context; + } + public static UrlHistoryDialog loadBackForwardList(long webViewFragmentId) { // Create an arguments bundle. Bundle argumentsBundle = new Bundle(); @@ -126,7 +145,7 @@ public class UrlHistoryDialog extends DialogFragment{ // Create a history array list. ArrayList historyArrayList = new ArrayList<>(); - // Populate the history array list, descending from `urlStringArrayList.size()` so that the newest entries are at the top. `-1` is needed because the history array list is zero-based. + // Populate the history array list, descending from the end of the list so that the newest entries are at the top. `-1` is needed because the history array list is zero-based. for (int i=webBackForwardList.getSize() -1; i >= 0; i--) { // Create a variable to store the favorite icon bitmap. Bitmap favoriteIconBitmap; @@ -214,14 +233,14 @@ public class UrlHistoryDialog extends DialogFragment{ // Only consume the click if it is not on the `currentPageId`. if (itemId != currentPageId) { - // Reset the current domain name so that navigation works if third-party requests are blocked. - nestedScrollWebView.resetCurrentDomainName(); + // Get a handle for the URL text view. + TextView urlTextView = view.findViewById(R.id.history_url_textview); - // Set navigating history so that the domain settings are applied when the new URL is loaded. - nestedScrollWebView.setNavigatingHistory(true); + // Get the URL. + String url = urlTextView.getText().toString(); - // Load the history entry. - nestedScrollWebView.goBackOrForward(currentPageId - itemId); + // Invoke the navigate history listener in the calling activity. These commands cannot be run here because they need access to `applyDomainSettings()`. + navigateHistoryListener.navigateHistory(url, currentPageId - itemId); // Dismiss the alert dialog. alertDialog.dismiss(); diff --git a/app/src/main/java/com/stoutner/privacybrowser/views/NestedScrollWebView.java b/app/src/main/java/com/stoutner/privacybrowser/views/NestedScrollWebView.java index c7122cb8..f8777455 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/views/NestedScrollWebView.java +++ b/app/src/main/java/com/stoutner/privacybrowser/views/NestedScrollWebView.java @@ -117,9 +117,6 @@ public class NestedScrollWebView extends WebView implements NestedScrollingChild // The ignore pinned domain information tracker. This is set when a user proceeds past a pinned mismatch dialog to prevent the dialog from showing again until after the domain changes. private boolean ignorePinnedDomainInformation; - // Track navigation of history. - private boolean navigatingHistory; - // The default or favorite icon. private Bitmap favoriteOrDefaultIcon; @@ -607,18 +604,6 @@ public class NestedScrollWebView extends WebView implements NestedScrollingChild } - // Navigating history. - public void setNavigatingHistory(boolean status) { - // Set the status of navigating history. - navigatingHistory = status; - } - - public boolean getNavigatingHistory() { - // Return the status of navigating history. - return navigatingHistory; - } - - // Favorite or default icon. public void initializeFavoriteIcon() { // Get the default favorite icon drawable. `ContextCompat` must be used until API >= 21. diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index 13527b01..4b397c5d 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -189,6 +189,7 @@ Yeni sekmede aç + Resmi Yeni Sekmede Aç URL\'yi kopyala URL\'yi indir E-posta adresi @@ -505,9 +506,9 @@ Tüm üçüncü taraf istekleri engellemek gizliliği arttırır, fakat çoğu web sitesinin çökmesine sebep olur. URL Modifikasyonu Google Analytics - URL\'den sonra gelen “?utm_” or “&utm_” ve diğer şeyleri kaldırır. + URL\'lerde “?utm_” ve “&utm_” ve onlardan sonra gelen her şey kaldırıldı. Facebook Tık ID\'leri - URL\'den sonra gelen “?fbclid=” or “&fbclid=” ve diğer şeyleri kaldırır. + URL\'lerde “?fbclid=”, “&fbclid=”, “?fbadid=”, ve “&fbadid=” ve onlardan sonra gelen her şey kaldırıldı. Twitter AMP yönlendirmeleri URL\'den sonra gelen “?amp=1” ve diğer şeyleri kaldırır. Tor -- 2.43.0