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=13d81cb9f5eb103e3e839de96804f2e408c4bb47;hp=d592b993d7c5fc8f097ee25e0758b0b04d753a04;hb=0b2da52fc661cf302cd94105620e54340d269f1d;hpb=247b22a2fb031f8b790c908e8d29daaa2d1a3472 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 d592b993..13d81cb9 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java +++ b/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java @@ -152,6 +152,7 @@ import com.stoutner.privacybrowser.helpers.BlocklistHelper; import com.stoutner.privacybrowser.helpers.BookmarksDatabaseHelper; import com.stoutner.privacybrowser.helpers.DomainsDatabaseHelper; import com.stoutner.privacybrowser.helpers.ProxyHelper; +import com.stoutner.privacybrowser.helpers.SanitizeUrlHelper; import com.stoutner.privacybrowser.views.NestedScrollWebView; import java.io.ByteArrayInputStream; @@ -182,6 +183,8 @@ import java.util.Set; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; +import kotlin.Pair; + public class MainWebViewActivity extends AppCompatActivity implements CreateBookmarkDialog.CreateBookmarkListener, CreateBookmarkFolderDialog.CreateBookmarkFolderListener, EditBookmarkFolderDialog.EditBookmarkFolderListener, FontSizeDialog.UpdateFontSizeListener, NavigationView.OnNavigationItemSelectedListener, OpenDialog.OpenListener, PinnedMismatchDialog.PinnedMismatchListener, PopulateBlocklists.PopulateBlocklistsListener, SaveDialog.SaveListener, UrlHistoryDialog.NavigateHistoryListener, @@ -272,13 +275,13 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook private int defaultProgressViewStartOffset; private int defaultProgressViewEndOffset; - // The URL sanitizers are set in `applyAppSettings()` and used in `sanitizeUrl()`. - private boolean sanitizeGoogleAnalytics; - private boolean sanitizeFacebookClickIds; - private boolean sanitizeTwitterAmpRedirects; + // Declare the helpers. + private BookmarksDatabaseHelper bookmarksDatabaseHelper; + private DomainsDatabaseHelper domainsDatabaseHelper; + private ProxyHelper proxyHelper; + private SanitizeUrlHelper sanitizeUrlHelper; // Declare the class variables - private BookmarksDatabaseHelper bookmarksDatabaseHelper; private boolean bottomAppBar; private boolean displayingFullScreenVideo; private boolean downloadWithExternalApp; @@ -288,9 +291,10 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook private boolean inFullScreenBrowsingMode; private boolean loadingNewIntent; private BroadcastReceiver orbotStatusBroadcastReceiver; - private ProxyHelper proxyHelper; private boolean reapplyAppSettingsOnRestart; private boolean reapplyDomainSettingsOnRestart; + private boolean sanitizeAmpRedirects; + private boolean sanitizeTrackingQueries; private boolean scrollAppBar; private boolean waitingForProxy; private String webViewDefaultUserAgent; @@ -534,12 +538,9 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Set the theme. setTheme(R.style.PrivacyBrowser); - // Set the content view. - if (bottomAppBar) { - setContentView(R.layout.main_framelayout_bottom_appbar); - } else { - setContentView(R.layout.main_framelayout_top_appbar); - } + // Set the content view according to the position of the app bar. + if (bottomAppBar) setContentView(R.layout.main_framelayout_bottom_appbar); + else setContentView(R.layout.main_framelayout_top_appbar); // Get handles for the views. rootFrameLayout = findViewById(R.id.root_framelayout); @@ -602,8 +603,11 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Store up to 100 tabs in memory. webViewPager.setOffscreenPageLimit(100); - // Instantiate the proxy helper. + // Instantiate the helpers. + bookmarksDatabaseHelper = new BookmarksDatabaseHelper(this); + domainsDatabaseHelper = new DomainsDatabaseHelper(this); proxyHelper = new ProxyHelper(); + sanitizeUrlHelper = new SanitizeUrlHelper(); // Initialize the app. initializeApp(); @@ -1849,24 +1853,45 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Consume the event. return true; - } else if (menuItemId == R.id.share_url) { // Share URL. - // Setup the share string. + } else if (menuItemId == R.id.share_message) { // Share a message. + // Prepare the share string. String shareString = currentWebView.getTitle() + " – " + currentWebView.getUrl(); // Create the share intent. - Intent shareIntent = new Intent(Intent.ACTION_SEND); + Intent shareMessageIntent = new Intent(Intent.ACTION_SEND); // Add the share string to the intent. - shareIntent.putExtra(Intent.EXTRA_TEXT, shareString); + shareMessageIntent.putExtra(Intent.EXTRA_TEXT, shareString); // Set the MIME type. - shareIntent.setType("text/plain"); + shareMessageIntent.setType("text/plain"); // Set the intent to open in a new task. - shareIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + shareMessageIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // Make it so. - startActivity(Intent.createChooser(shareIntent, getString(R.string.share_url))); + startActivity(Intent.createChooser(shareMessageIntent, getString(R.string.share_message))); + + // Consume the event. + return true; + } else if (menuItemId == R.id.share_url) { // Share URL. + // Create the share intent. + Intent shareUrlIntent = new Intent(Intent.ACTION_SEND); + + // Add the URL to the intent. + shareUrlIntent.putExtra(Intent.EXTRA_TEXT, currentWebView.getUrl()); + + // Add the title to the intent. + shareUrlIntent.putExtra(Intent.EXTRA_SUBJECT, currentWebView.getTitle()); + + // Set the MIME type. + shareUrlIntent.setType("text/plain"); + + // Set the intent to open in a new task. + shareUrlIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + + //Make it so. + startActivity(Intent.createChooser(shareUrlIntent, getString(R.string.share_url))); // Consume the event. return true; @@ -1933,9 +1958,6 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook Uri currentUri = Uri.parse(currentWebView.getUrl()); String currentDomain = currentUri.getHost(); - // Initialize the database handler. The `0` specifies the database version, but that is ignored and set instead using a constant in `DomainsDatabaseHelper`. - DomainsDatabaseHelper domainsDatabaseHelper = new DomainsDatabaseHelper(this, null, null, 0); - // Create the domain and store the database ID. int newDomainDatabaseId = domainsDatabaseHelper.addDomain(currentDomain); @@ -3363,9 +3385,6 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook drawerLayout.setDrawerTitle(GravityCompat.START, getString(R.string.navigation_drawer)); drawerLayout.setDrawerTitle(GravityCompat.END, getString(R.string.bookmarks)); - // Initialize the bookmarks database helper. The `0` specifies a database version, but that is ignored and set instead using a constant in `BookmarksDatabaseHelper`. - bookmarksDatabaseHelper = new BookmarksDatabaseHelper(this, null, null, 0); - // Initialize `currentBookmarksFolder`. `""` is the home folder in the database. currentBookmarksFolder = ""; @@ -3429,7 +3448,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook addNewTab(bookmarkCursor.getString(bookmarkCursor.getColumnIndexOrThrow(BookmarksDatabaseHelper.BOOKMARK_URL)), false); // Display a snackbar. - Snackbar.make(currentWebView, R.string.bookmark_opened_in_background, Snackbar.LENGTH_SHORT).show(); + Snackbar.make(drawerLayout, R.string.bookmark_opened_in_background, Snackbar.LENGTH_SHORT).show(); } // Consume the event. @@ -3500,9 +3519,8 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Store the values from the shared preferences in variables. incognitoModeEnabled = sharedPreferences.getBoolean("incognito_mode", false); - sanitizeGoogleAnalytics = sharedPreferences.getBoolean("google_analytics", true); - sanitizeFacebookClickIds = sharedPreferences.getBoolean("facebook_click_ids", true); - sanitizeTwitterAmpRedirects = sharedPreferences.getBoolean("twitter_amp_redirects", true); + sanitizeTrackingQueries = sharedPreferences.getBoolean(getString(R.string.tracking_queries_key), true); + sanitizeAmpRedirects = sharedPreferences.getBoolean(getString(R.string.amp_redirects_key), true); proxyMode = sharedPreferences.getString("proxy", getString(R.string.proxy_default_value)); fullScreenBrowsingModeEnabled = sharedPreferences.getBoolean("full_screen_browsing_mode", false); downloadWithExternalApp = sharedPreferences.getBoolean(getString(R.string.download_with_external_app_key), false); @@ -3531,8 +3549,26 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Apply the proxy. applyProxy(false); - // Adjust the layout and scrolling parameters if the app bar is at the top of the screen. - if (!bottomAppBar) { + // Adjust the layout and scrolling parameters according to the position of the app bar. + if (bottomAppBar) { // The app bar is on the bottom. + // Adjust the UI. + if (scrollAppBar || (inFullScreenBrowsingMode && hideAppBar)) { // The app bar scrolls or full screen browsing mode is engaged with the app bar hidden. + // Reset the WebView padding to fill the available space. + swipeRefreshLayout.setPadding(0, 0, 0, 0); + } else { // The app bar doesn't scroll or full screen browsing mode is not engaged with the app bar hidden. + // Move the WebView above the app bar layout. + swipeRefreshLayout.setPadding(0, 0, 0, appBarHeight); + + // Show the app bar if it is scrolled off the screen. + if (appBarLayout.getTranslationY() != 0) { + // Animate the bottom app bar onto the screen. + objectAnimator = ObjectAnimator.ofFloat(appBarLayout, "translationY", 0); + + // Make it so. + objectAnimator.start(); + } + } + } else { // The app bar is on the top. // Get the current layout parameters. Using coordinator layout parameters allows the `setBehavior()` command and using app bar layout parameters allows the `setScrollFlags()` command. CoordinatorLayout.LayoutParams swipeRefreshLayoutParams = (CoordinatorLayout.LayoutParams) swipeRefreshLayout.getLayoutParams(); AppBarLayout.LayoutParams toolbarLayoutParams = (AppBarLayout.LayoutParams) toolbar.getLayoutParams(); @@ -3700,10 +3736,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook } } - // Initialize the database handler. The `0` specifies the database version, but that is ignored and set instead using a constant in `DomainsDatabaseHelper`. - DomainsDatabaseHelper domainsDatabaseHelper = new DomainsDatabaseHelper(this, null, null, 0); - - // Get a full cursor from `domainsDatabaseHelper`. + // Get a full domain name cursor. Cursor domainNameCursor = domainsDatabaseHelper.getDomainNameCursorOrderedByDomain(); // Initialize `domainSettingsSet`. @@ -3712,7 +3745,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Get the domain name column index. int domainNameColumnIndex = domainNameCursor.getColumnIndexOrThrow(DomainsDatabaseHelper.DOMAIN_NAME); - // Populate `domainSettingsSet`. + // Populate the domain settings set. for (int i = 0; i < domainNameCursor.getCount(); i++) { // Move the domains cursor to the current row. domainNameCursor.moveToPosition(i); @@ -3721,7 +3754,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook domainSettingsSet.add(domainNameCursor.getString(domainNameColumnIndex)); } - // Close `domainNameCursor. + // Close the domain name cursor. domainNameCursor.close(); // Initialize the domain name in database variable. @@ -3740,7 +3773,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook } // Check all the subdomains of the host name against wildcard domains in the domain cursor. - while (!nestedScrollWebView.getDomainSettingsApplied() && newHostName.contains(".")) { // Stop checking if domain settings are already applied or there are no more `.` in the host name. + while (!nestedScrollWebView.getDomainSettingsApplied() && newHostName.contains(".")) { // Stop checking if domain settings are already applied or there are no more `.` in the hostname. if (domainSettingsSet.contains("*." + newHostName)) { // Check the host name prepended by `*.`. // Set the domain settings applied tracker to true. nestedScrollWebView.setDomainSettingsApplied(true); @@ -3776,12 +3809,17 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook String[] userAgentDataArray = getResources().getStringArray(R.array.user_agent_data); if (nestedScrollWebView.getDomainSettingsApplied()) { // The url has custom domain settings. - // Get a cursor for the current host and move it to the first position. + // Remove the incorrect lint warning below that the domain name in database might be null. + assert domainNameInDatabase != null; + + // Get a cursor for the current host. Cursor currentDomainSettingsCursor = domainsDatabaseHelper.getCursorForDomainName(domainNameInDatabase); + + // Move to the first position. currentDomainSettingsCursor.moveToFirst(); // Get the settings from the cursor. - nestedScrollWebView.setDomainSettingsDatabaseId(currentDomainSettingsCursor.getInt(currentDomainSettingsCursor.getColumnIndexOrThrow(DomainsDatabaseHelper._ID))); + nestedScrollWebView.setDomainSettingsDatabaseId(currentDomainSettingsCursor.getInt(currentDomainSettingsCursor.getColumnIndexOrThrow(DomainsDatabaseHelper.ID))); nestedScrollWebView.getSettings().setJavaScriptEnabled(currentDomainSettingsCursor.getInt(currentDomainSettingsCursor.getColumnIndexOrThrow(DomainsDatabaseHelper.ENABLE_JAVASCRIPT)) == 1); nestedScrollWebView.setAcceptCookies(currentDomainSettingsCursor.getInt(currentDomainSettingsCursor.getColumnIndexOrThrow(DomainsDatabaseHelper.COOKIES)) == 1); nestedScrollWebView.getSettings().setDomStorageEnabled(currentDomainSettingsCursor.getInt(currentDomainSettingsCursor.getColumnIndexOrThrow(DomainsDatabaseHelper.ENABLE_DOM_STORAGE)) == 1); @@ -4456,49 +4494,13 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook } private String sanitizeUrl(String url) { - // Sanitize Google Analytics. - if (sanitizeGoogleAnalytics) { - // Remove `?utm_`. - if (url.contains("?utm_")) { - url = url.substring(0, url.indexOf("?utm_")); - } - - // Remove `&utm_`. - if (url.contains("&utm_")) { - url = url.substring(0, url.indexOf("&utm_")); - } - } - - // Sanitize Facebook Click IDs. - if (sanitizeFacebookClickIds) { - // Remove `?fbclid=`. - if (url.contains("?fbclid=")) { - url = url.substring(0, url.indexOf("?fbclid=")); - } - - // Remove `&fbclid=`. - if (url.contains("&fbclid=")) { - url = url.substring(0, url.indexOf("&fbclid=")); - } - - // Remove `?fbadid=`. - if (url.contains("?fbadid=")) { - url = url.substring(0, url.indexOf("?fbadid=")); - } - - // Remove `&fbadid=`. - if (url.contains("&fbadid=")) { - url = url.substring(0, url.indexOf("&fbadid=")); - } - } + // Sanitize tracking queries. + if (sanitizeTrackingQueries) + url = sanitizeUrlHelper.sanitizeTrackingQueries(url); - // Sanitize Twitter AMP redirects. - if (sanitizeTwitterAmpRedirects) { - // Remove `?amp=1`. - if (url.contains("?amp=1")) { - url = url.substring(0, url.indexOf("?amp=1")); - } - } + // Sanitize AMP redirects. + if (sanitizeAmpRedirects) + url = sanitizeUrlHelper.sanitizeAmpRedirects(url); // Return the sanitized URL. return url; @@ -5094,7 +5096,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Toggle the full screen browsing mode. if (inFullScreenBrowsingMode) { // Switch to full screen mode. // Hide the app bar if specified. - if (hideAppBar) { + if (hideAppBar) { // The app bar is hidden. // Close the find on page bar if it is visible. closeFindOnPage(null); @@ -5104,8 +5106,11 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Hide the action bar. actionBar.hide(); - // Set layout and scrolling parameters if the app bar is at the top of the screen. - if (!bottomAppBar) { + // Set layout and scrolling parameters according to the position of the app bar. + if (bottomAppBar) { // The app bar is at the bottom. + // Reset the WebView padding to fill the available space. + swipeRefreshLayout.setPadding(0, 0, 0, 0); + } else { // The app bar is at the top. // Check to see if the app bar is normally scrolled. if (scrollAppBar) { // The app bar is scrolled when it is displayed. // Get the swipe refresh layout parameters. @@ -5121,6 +5126,18 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook swipeRefreshLayout.setProgressViewOffset(false, -200, defaultProgressViewEndOffset); } } + } else { // The app bar is not hidden. + // Adjust the UI for the bottom app bar. + if (bottomAppBar) { + // Adjust the UI according to the scrolling of the app bar. + if (scrollAppBar) { + // Reset the WebView padding to fill the available space. + swipeRefreshLayout.setPadding(0, 0, 0, 0); + } else { + // Move the WebView above the app bar layout. + swipeRefreshLayout.setPadding(0, 0, 0, appBarHeight); + } + } } /* Hide the system bars. @@ -5139,23 +5156,32 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Show the action bar. actionBar.show(); + } - // Set layout and scrolling parameters if the app bar is at the top of the screen. - if (!bottomAppBar) { - // Check to see if the app bar is normally scrolled. - if (scrollAppBar) { // The app bar is scrolled when it is displayed. - // Get the swipe refresh layout parameters. - CoordinatorLayout.LayoutParams swipeRefreshLayoutParams = (CoordinatorLayout.LayoutParams) swipeRefreshLayout.getLayoutParams(); - - // Add the off-screen scrolling layout. - swipeRefreshLayoutParams.setBehavior(new AppBarLayout.ScrollingViewBehavior()); - } else { // The app bar is not scrolled when it is displayed. - // The swipe refresh layout must be manually moved below the app bar layout. - swipeRefreshLayout.setPadding(0, appBarHeight, 0, 0); - - // The swipe to refresh circle doesn't always hide itself completely unless it is moved up 10 pixels. - swipeRefreshLayout.setProgressViewOffset(false, defaultProgressViewStartOffset - 10 + appBarHeight, defaultProgressViewEndOffset + appBarHeight); - } + // Set layout and scrolling parameters according to the position of the app bar. + if (bottomAppBar) { // The app bar is at the bottom. + // Adjust the UI. + if (scrollAppBar) { + // Reset the WebView padding to fill the available space. + swipeRefreshLayout.setPadding(0, 0, 0, 0); + } else { + // Move the WebView above the app bar layout. + swipeRefreshLayout.setPadding(0, 0, 0, appBarHeight); + } + } else { // The app bar is at the top. + // Check to see if the app bar is normally scrolled. + if (scrollAppBar) { // The app bar is scrolled when it is displayed. + // Get the swipe refresh layout parameters. + CoordinatorLayout.LayoutParams swipeRefreshLayoutParams = (CoordinatorLayout.LayoutParams) swipeRefreshLayout.getLayoutParams(); + + // Add the off-screen scrolling layout. + swipeRefreshLayoutParams.setBehavior(new AppBarLayout.ScrollingViewBehavior()); + } else { // The app bar is not scrolled when it is displayed. + // The swipe refresh layout must be manually moved below the app bar layout. + swipeRefreshLayout.setPadding(0, appBarHeight, 0, 0); + + // The swipe to refresh circle doesn't always hide itself completely unless it is moved up 10 pixels. + swipeRefreshLayout.setProgressViewOffset(false, defaultProgressViewStartOffset - 10 + appBarHeight, defaultProgressViewEndOffset + appBarHeight); } } @@ -5169,6 +5195,30 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook return false; } } + + @Override + public boolean onFling(MotionEvent motionEvent1, MotionEvent motionEvent2, float velocityX, float velocityY) { + // Scroll the bottom app bar if enabled. + if (bottomAppBar && scrollAppBar && !objectAnimator.isRunning()) { + // Calculate the Y change. + float motionY = motionEvent2.getY() - motionEvent1.getY(); + + // Scroll the app bar if the change is greater than 100 pixels. + if (motionY > 50) { + // Animate the bottom app bar onto the screen. + objectAnimator = ObjectAnimator.ofFloat(appBarLayout, "translationY", 0); + } else if (motionY < -50) { + // Animate the bottom app bar off the screen. + objectAnimator = ObjectAnimator.ofFloat(appBarLayout, "translationY", appBarLayout.getHeight()); + } + + // Make it so. + objectAnimator.start(); + } + + // Do not consume the event. + return false; + } }); // Pass all touch events on the WebView through the double-tap gesture detector. @@ -5242,7 +5292,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook } }); - // Update the status of swipe to refresh based on the scroll position of the nested scroll WebView. Also reinforce full screen browsing mode. + // Process scroll changes. nestedScrollWebView.setOnScrollChangeListener((view, scrollX, scrollY, oldScrollX, oldScrollY) -> { // Set the swipe to refresh status. if (nestedScrollWebView.getSwipeToRefresh()) { @@ -5253,23 +5303,6 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook swipeRefreshLayout.setEnabled(false); } - // Scroll the bottom app bar if enabled. - if (bottomAppBar && scrollAppBar && !objectAnimator.isRunning()) { - if (scrollY < oldScrollY) { // The WebView was scrolled down. - // Animate the bottom app bar onto the screen. - objectAnimator = ObjectAnimator.ofFloat(appBarLayout, "translationY", 0); - - // Make it so. - objectAnimator.start(); - } else if (scrollY > oldScrollY) { // The WebView was scrolled up. - // Animate the bottom app bar off the screen. - objectAnimator = ObjectAnimator.ofFloat(appBarLayout, "translationY", appBarLayout.getHeight()); - - // Make it so. - objectAnimator.start(); - } - } - // Reinforce the system UI visibility flags if in full screen browsing mode. // This hides the status and navigation bars, which are displayed if other elements are shown, like dialog boxes, the options menu, or the keyboard. if (inFullScreenBrowsingMode) { @@ -5882,8 +5915,21 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook @Override public void onPageStarted(WebView view, String url, Bitmap favicon) { - // Set the padding and layout settings if the app bar is at the top of the screen. - if (!bottomAppBar) { + // Get the app bar layout height. This can't be done in `applyAppSettings()` because the app bar is not yet populated there. + // This should only be populated if it is greater than 0 because otherwise it will be reset to 0 if the app bar is hidden in full screen browsing mode. + if (appBarLayout.getHeight() > 0) appBarHeight = appBarLayout.getHeight(); + + // Set the padding and layout settings according to the position of the app bar. + if (bottomAppBar) { // The app bar is on the bottom. + // Adjust the UI. + if (scrollAppBar || (inFullScreenBrowsingMode && hideAppBar)) { // The app bar scrolls or full screen browsing mode is engaged with the app bar hidden. + // Reset the WebView padding to fill the available space. + swipeRefreshLayout.setPadding(0, 0, 0, 0); + } else { // The app bar doesn't scroll or full screen browsing mode is not engaged with the app bar hidden. + // Move the WebView above the app bar layout. + swipeRefreshLayout.setPadding(0, 0, 0, appBarHeight); + } + } else { // The app bar is on the top. // Set the top padding of the swipe refresh layout according to the app bar scrolling preference. This can't be done in `appAppSettings()` because the app bar is not yet populated there. if (scrollAppBar || (inFullScreenBrowsingMode && hideAppBar)) { // No padding is needed because it will automatically be placed below the app bar layout due to the scrolling layout behavior. @@ -5892,9 +5938,6 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // The swipe to refresh circle doesn't always hide itself completely unless it is moved up 10 pixels. swipeRefreshLayout.setProgressViewOffset(false, defaultProgressViewStartOffset - 10, defaultProgressViewEndOffset); } else { - // Get the app bar layout height. This can't be done in `applyAppSettings()` because the app bar is not yet populated there. - appBarHeight = appBarLayout.getHeight(); - // The swipe refresh layout must be manually moved below the app bar layout. swipeRefreshLayout.setPadding(0, appBarHeight, 0, 0); @@ -6095,11 +6138,11 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Proceed to the website if the current SSL website certificate matches the pinned domain certificate. if (nestedScrollWebView.hasPinnedSslCertificate()) { // Get the pinned SSL certificate. - ArrayList pinnedSslCertificateArrayList = nestedScrollWebView.getPinnedSslCertificate(); + Pair pinnedSslCertificatePair = nestedScrollWebView.getPinnedSslCertificate(); // Extract the arrays from the array list. - String[] pinnedSslCertificateStringArray = (String[]) pinnedSslCertificateArrayList.get(0); - Date[] pinnedSslCertificateDateArray = (Date[]) pinnedSslCertificateArrayList.get(1); + String[] pinnedSslCertificateStringArray = pinnedSslCertificatePair.getFirst(); + Date[] pinnedSslCertificateDateArray = pinnedSslCertificatePair.getSecond(); // Check if the current SSL certificate matches the pinned certificate. if (currentWebsiteIssuedToCName.equals(pinnedSslCertificateStringArray[0]) && currentWebsiteIssuedToOName.equals(pinnedSslCertificateStringArray[1]) &&