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=8344d5c4e168a4f15adfe9a581a92edc0ed9fcd3;hp=3d27a4cf61d0782be71bbe673cc29dad58082b41;hb=9338dfa2f8a295736d35e4f468f0c0ba573a1b58;hpb=333ec579b52efbfbad89e0150c7c320822ba9ecf 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 3d27a4cf..8344d5c4 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java +++ b/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java @@ -118,6 +118,7 @@ import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; import androidx.viewpager.widget.ViewPager; import androidx.webkit.WebSettingsCompat; import androidx.webkit.WebViewFeature; +import kotlin.Pair; import com.google.android.material.appbar.AppBarLayout; import com.google.android.material.floatingactionbutton.FloatingActionButton; @@ -529,17 +530,14 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook } // Enable the drawing of the entire webpage. This makes it possible to save a website image. This must be done before anything else happens with the WebView. - //WebView.enableSlowWholeDocumentDraw(); Temporarily disabled due to . + WebView.enableSlowWholeDocumentDraw(); // 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); @@ -1849,24 +1847,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,8 +1952,8 @@ 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); + // Initialize the database handler. + DomainsDatabaseHelper domainsDatabaseHelper = new DomainsDatabaseHelper(this); // Create the domain and store the database ID. int newDomainDatabaseId = domainsDatabaseHelper.addDomain(currentDomain); @@ -3363,8 +3382,8 @@ 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 the bookmarks database helper. + bookmarksDatabaseHelper = new BookmarksDatabaseHelper(this); // Initialize `currentBookmarksFolder`. `""` is the home folder in the database. currentBookmarksFolder = ""; @@ -3531,8 +3550,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,8 +3737,8 @@ 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); + // Initialize the database handler. + DomainsDatabaseHelper domainsDatabaseHelper = new DomainsDatabaseHelper(this); // Get a full cursor from `domainsDatabaseHelper`. Cursor domainNameCursor = domainsDatabaseHelper.getDomainNameCursorOrderedByDomain(); @@ -3712,7 +3749,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 +3758,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 +3777,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 +3813,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); @@ -5094,7 +5136,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 +5146,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 +5166,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 +5196,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 +5235,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 +5332,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 +5343,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 +5955,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 +5978,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 +6178,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]) &&