X-Git-Url: https://gitweb.stoutner.com/?p=PrivacyBrowserAndroid.git;a=blobdiff_plain;f=app%2Fsrc%2Fmain%2Fjava%2Fcom%2Fstoutner%2Fprivacybrowser%2Fviews%2FNestedScrollWebView.java;h=cf1e56ce46d4a420581115010ce22fc881c20a0a;hp=f7d57b68065e7da54c39e25b2680bd29700e079c;hb=fa3b8b382eb5ed86c598e3b126d1ef5dd117c5be;hpb=fe788514a50a591f9722ededc13e608ceb268bb8 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 f7d57b68..cf1e56ce 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/views/NestedScrollWebView.java +++ b/app/src/main/java/com/stoutner/privacybrowser/views/NestedScrollWebView.java @@ -20,15 +20,23 @@ package com.stoutner.privacybrowser.views; import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.drawable.BitmapDrawable; +import android.graphics.drawable.Drawable; import android.util.AttributeSet; import android.view.MotionEvent; +import android.webkit.HttpAuthHandler; +import android.webkit.SslErrorHandler; import android.webkit.WebView; import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; import androidx.core.view.NestedScrollingChild2; import androidx.core.view.NestedScrollingChildHelper; import androidx.core.view.ViewCompat; +import com.stoutner.privacybrowser.R; + import java.util.ArrayList; import java.util.Date; @@ -46,6 +54,10 @@ public class NestedScrollWebView extends WebView implements NestedScrollingChild // Keep a copy of the WebView fragment ID. private long webViewFragmentId; + // Store the handlers. + private SslErrorHandler sslErrorHandler; + private HttpAuthHandler httpAuthHandler; + // Track if domain settings are applied to this nested scroll WebView and, if so, the database ID. private boolean domainSettingsApplied; private int domainSettingsDatabaseId; @@ -53,6 +65,12 @@ public class NestedScrollWebView extends WebView implements NestedScrollingChild // Keep track of when the domain name changes so that domain settings can be reapplied. This should never be null. private String currentDomainName = ""; + // Track the status of first-party cookies. + private boolean acceptFirstPartyCookies; + + // Track the domain settings JavaScript status. This can be removed once night mode does not require JavaScript. + private boolean domainSettingsJavaScriptEnabled; + // Track the resource requests. private ArrayList resourceRequests = new ArrayList<>(); private boolean easyListEnabled; @@ -91,6 +109,18 @@ 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; + + // Track night mode. + private boolean nightMode; + + // Track swipe to refresh. + private boolean swipeToRefresh; + // The nested scrolling child helper is used throughout the class. private NestedScrollingChildHelper nestedScrollingChildHelper; @@ -137,6 +167,40 @@ public class NestedScrollWebView extends WebView implements NestedScrollingChild } + // SSL error handler. + public void setSslErrorHandler(SslErrorHandler sslErrorHandler) { + // Store the current SSL error handler. + this.sslErrorHandler = sslErrorHandler; + } + + public SslErrorHandler getSslErrorHandler() { + // Return the current SSL error handler. + return sslErrorHandler; + } + + public void resetSslErrorHandler() { + // Reset the current SSL error handler. + sslErrorHandler = null; + } + + + // HTTP authentication handler. + public void setHttpAuthHandler(HttpAuthHandler httpAuthHandler) { + // Store the current HTTP authentication handler. + this.httpAuthHandler = httpAuthHandler; + } + + public HttpAuthHandler getHttpAuthHandler() { + // Return the current HTTP authentication handler. + return httpAuthHandler; + } + + public void resetHttpAuthHandler() { + // Reset the current HTTP authentication handler. + httpAuthHandler = null; + } + + // Domain settings. public void setDomainSettingsApplied(boolean applied) { // Store the domain settings applied status. @@ -178,6 +242,30 @@ public class NestedScrollWebView extends WebView implements NestedScrollingChild } + // First-party cookies. + public void setAcceptFirstPartyCookies(boolean status) { + // Store the accept first-party cookies status. + acceptFirstPartyCookies = status; + } + + public boolean getAcceptFirstPartyCookies() { + // Return the accept first-party cookies status. + return acceptFirstPartyCookies; + } + + + // Domain settings JavaScript enabled. This can be removed once night mode does not require JavaScript. + public void setDomainSettingsJavaScriptEnabled(boolean status) { + // Store the domain settings JavaScript status. + domainSettingsJavaScriptEnabled = status; + } + + public boolean getDomainSettingsJavaScriptEnabled() { + // Return the domain settings JavaScript status. + return domainSettingsJavaScriptEnabled; + } + + // Resource requests. public void addResourceRequest(String[] resourceRequest) { // Add the resource request to the list. @@ -466,16 +554,84 @@ public class NestedScrollWebView extends WebView implements NestedScrollingChild } - // Ignore pinned information. The syntax looks better as written, even if it is always inverted. + // Ignore pinned information. + public void setIgnorePinnedDomainInformation(boolean status) { + // Set the status of the ignore pinned domain information tracker. + ignorePinnedDomainInformation = status; + } + + // The syntax looks better as written, even if it is always inverted. @SuppressWarnings("BooleanMethodIsAlwaysInverted") public boolean ignorePinnedDomainInformation() { // Return the status of the ignore pinned domain information tracker. return ignorePinnedDomainInformation; } - public void setIgnorePinnedDomainInformation(boolean status) { - // Set the status of the ignore pinned domain information tracker. - ignorePinnedDomainInformation = status; + + // 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. + Drawable favoriteIconDrawable = ContextCompat.getDrawable(getContext(), R.drawable.world); + + // Cast the favorite icon drawable to a bitmap drawable. + BitmapDrawable favoriteIconBitmapDrawable = (BitmapDrawable) favoriteIconDrawable; + + // Remove the incorrect warning below that the favorite icon bitmap drawable might be null. + assert favoriteIconBitmapDrawable != null; + + // Store the default icon bitmap. + favoriteOrDefaultIcon = favoriteIconBitmapDrawable.getBitmap(); + } + + public void setFavoriteOrDefaultIcon(Bitmap icon) { + // Scale the favorite icon bitmap down if it is larger than 256 x 256. Filtering uses bilinear interpolation. + if ((icon.getHeight() > 256) || (icon.getWidth() > 256)) { + favoriteOrDefaultIcon = Bitmap.createScaledBitmap(icon, 256, 256, true); + } else { + // Store the icon as presented. + favoriteOrDefaultIcon = icon; + } + } + + public Bitmap getFavoriteOrDefaultIcon() { + // Return the favorite or default icon. + return favoriteOrDefaultIcon; + } + + + // Night mode. + public void setNightMode(boolean status) { + // Store the night mode status. + nightMode = status; + } + + public boolean getNightMode() { + // Return the night mode status. + return nightMode; + } + + + // Swipe to refresh. + public void setSwipeToRefresh(boolean status) { + // Store the swipe to refresh status. + swipeToRefresh = status; + } + + public boolean getSwipeToRefresh() { + // Return the swipe to refresh status. + return swipeToRefresh; } @@ -520,12 +676,13 @@ public class NestedScrollWebView extends WebView implements NestedScrollingChild // Dispatch the nested pre-school. This scrolls the app bar if it needs it. `offsetInWindow` will be returned with an updated value. if (dispatchNestedPreScroll(0, preScrollDeltaY, consumedScroll, offsetInWindow)) { // Update the scroll delta Y if some of it was consumed. + // There is currently a bug in Android where if scrolling up at a certain slow speed the input can lock the pre scroll and continue to consume it after the app bar is fully displayed. scrollDeltaY = preScrollDeltaY - consumedScroll[1]; } // Check to see if the WebView is at the top and and the scroll action is downward. if ((webViewYPosition == 0) && (scrollDeltaY < 0)) { // Swipe to refresh is being engaged. - // Stop the nested scroll so that swipe to refresh has complete control. + // Stop the nested scroll so that swipe to refresh has complete control. This way releasing the scroll to refresh circle doesn't scroll the WebView at the same time. stopNestedScroll(); } else { // Swipe to refresh is not being engaged. // Start the nested scroll so that the app bar can scroll off the screen.