X-Git-Url: https://gitweb.stoutner.com/?a=blobdiff_plain;f=app%2Fsrc%2Fmain%2Fjava%2Fcom%2Fstoutner%2Fprivacybrowser%2Factivities%2FMainWebViewActivity.java;h=96098947696d915603fa7e53d69d4b4de556a812;hb=9c9159715c89e30aec11ae7e7a1d7591006e5cbe;hp=2b15aa4c2993177cead252bab7bf8d1c4a795714;hpb=97e0d95eff56498ebae87dd90ad2299e0d1fb0cf;p=PrivacyBrowserAndroid.git 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 2b15aa4c..96098947 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java +++ b/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java @@ -1,5 +1,5 @@ /* - * Copyright © 2015-2018 Soren Stoutner . + * Copyright © 2015-2019 Soren Stoutner . * * Download cookie code contributed 2017 Hendrik Knackstedt. Copyright assigned to Soren Stoutner . * @@ -95,6 +95,7 @@ import android.webkit.ValueCallback; import android.webkit.WebBackForwardList; import android.webkit.WebChromeClient; import android.webkit.WebResourceResponse; +import android.webkit.WebSettings; import android.webkit.WebStorage; import android.webkit.WebView; import android.webkit.WebViewClient; @@ -447,6 +448,11 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook private ForegroundColorSpan initialGrayColorSpan; private ForegroundColorSpan finalGrayColorSpan; + // The drawer header padding variables are used in `onCreate()` and `onConfigurationChanged()`. + private int drawerHeaderPaddingLeftAndRight; + private int drawerHeaderPaddingTop; + private int drawerHeaderPaddingBottom; + // `sslErrorHandler` is used in `onCreate()`, `onSslErrorCancel()`, and `onSslErrorProceed`. private SslErrorHandler sslErrorHandler; @@ -764,7 +770,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Update `findOnPageCountTextView`. mainWebView.setFindListener(new WebView.FindListener() { // Get a handle for `findOnPageCountTextView`. - final TextView findOnPageCountTextView = (TextView) findViewById(R.id.find_on_page_count_textview); + final TextView findOnPageCountTextView = findViewById(R.id.find_on_page_count_textview); @Override public void onFindResultReceived(int activeMatchOrdinal, int numberOfMatches, boolean isDoneCounting) { @@ -858,7 +864,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook int databaseID = (int) id; // Get the bookmark cursor for this ID and move it to the first row. - Cursor bookmarkCursor = bookmarksDatabaseHelper.getBookmarkCursor(databaseID); + Cursor bookmarkCursor = bookmarksDatabaseHelper.getBookmark(databaseID); bookmarkCursor.moveToFirst(); // Act upon the bookmark according to the type. @@ -912,11 +918,11 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook float screenDensity = resources.getDisplayMetrics().density; // Calculate the drawer header padding. This is used to move the text in the drawer headers below any cutouts. - int drawerHeaderPaddingLeftAndRight = (int) (15 * screenDensity); - int drawerHeaderPaddingTop = statusBarPixelSize + (int) (4 * screenDensity); - int drawerHeaderPaddingBottom = (int) (8 * screenDensity); + drawerHeaderPaddingLeftAndRight = (int) (15 * screenDensity); + drawerHeaderPaddingTop = statusBarPixelSize + (int) (4 * screenDensity); + drawerHeaderPaddingBottom = (int) (8 * screenDensity); - // The drawer listener is used to update the navigation menu. + // The drawer listener is used to update the navigation menu.` drawerLayout.addDrawerListener(new DrawerLayout.DrawerListener() { @Override public void onDrawerSlide(@NonNull View drawerView, float slideOffset) { @@ -977,17 +983,17 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook if (nightMode) { // `background-color: #212121` sets the background to be dark gray. `color: #BDBDBD` sets the text color to be light gray. `box-shadow: none` removes a lower underline on links // used by WordPress. `text-decoration: none` removes all text underlines. `text-shadow: none` removes text shadows, which usually have a hard coded color. - // `border: none` removes all borders, which can also be used to underline text. - // `a {color: #1565C0}` sets links to be a dark blue. `!important` takes precedent over any existing sub-settings. + // `border: none` removes all borders, which can also be used to underline text. `a {color: #1565C0}` sets links to be a dark blue. + // `::selection {background: #0D47A1}' sets the text selection highlight color to be a dark blue. `!important` takes precedent over any existing sub-settings. mainWebView.evaluateJavascript("(function() {var parent = document.getElementsByTagName('head').item(0); var style = document.createElement('style'); style.type = 'text/css'; " + "style.innerHTML = '* {background-color: #212121 !important; color: #BDBDBD !important; box-shadow: none !important; text-decoration: none !important;" + - "text-shadow: none !important; border: none !important;} a {color: #1565C0 !important;}'; parent.appendChild(style)})()", value -> { + "text-shadow: none !important; border: none !important;} a {color: #1565C0 !important;} ::selection {background: #0D47A1 !important;}'; parent.appendChild(style)})()", value -> { // Initialize a handler to display `mainWebView`. Handler displayWebViewHandler = new Handler(); // Setup a runnable to display `mainWebView` after a delay to allow the CSS to be applied. Runnable displayWebViewRunnable = () -> { - // Only display `mainWebView` if the progress bar is one. This prevents the display of the `WebView` while it is still loading. + // Only display `mainWebView` if the progress bar is gone. This prevents the display of the `WebView` while it is still loading. if (progressBar.getVisibility() == View.GONE) { mainWebView.setVisibility(View.VISIBLE); } @@ -1216,10 +1222,15 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Hide zoom controls. mainWebView.getSettings().setDisplayZoomControls(false); - // Set `mainWebView` to use a wide viewport. Otherwise, some web pages will be scrunched and some content will render outside the screen. + // Don't allow mixed content (HTTP and HTTPS) on the same website. + if (Build.VERSION.SDK_INT >= 21) { + mainWebView.getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_NEVER_ALLOW); + } + + // Set the WebView to use a wide viewport. Otherwise, some web pages will be scrunched and some content will render outside the screen. mainWebView.getSettings().setUseWideViewPort(true); - // Set `mainWebView` to load in overview mode (zoomed out to the maximum width). + // Set the WebView to load in overview mode (zoomed out to the maximum width). mainWebView.getSettings().setLoadWithOverviewMode(true); // Explicitly disable geolocation. @@ -1606,7 +1617,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Check to see if Privacy Browser is waiting on Orbot. if (!waitingForOrbot) { // We are not waiting on Orbot, so we need to process the URL. - // We need to update `formattedUrlString` at the beginning of the load, so that if the user toggles JavaScript during the load the new website is reloaded. + // The formatted URL string must be updated at the beginning of the load, so that if the user toggles JavaScript during the load the new website is reloaded. formattedUrlString = url; // Display the formatted URL text. @@ -1720,10 +1731,10 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Apply the domain settings. This clears any settings from the previous domain. applyDomainSettings(formattedUrlString, true, false); } else { // `WebView` has loaded a webpage. - // Set `formattedUrlString`. - formattedUrlString = url; + // Set the formatted URL string. Getting the URL from the WebView instead of using the one provided by `onPageFinished` makes websites like YouTube function correctly. + formattedUrlString = mainWebView.getUrl(); - // Only update `urlTextBox` if the user is not typing in it. + // Only update the URL text box if the user is not typing in it. if (!urlTextBox.hasFocus()) { // Display the formatted URL text. urlTextBox.setText(formattedUrlString); @@ -2852,21 +2863,39 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook printManager.print(getString(R.string.privacy_browser_web_page), printDocumentAdapter, null); return true; + case R.id.find_on_page: + // Hide the URL app bar. + supportAppBar.setVisibility(View.GONE); + + // Show the Find on Page `RelativeLayout`. + findOnPageLinearLayout.setVisibility(View.VISIBLE); + + // Display the keyboard. We have to wait 200 ms before running the command to work around a bug in Android. + // http://stackoverflow.com/questions/5520085/android-show-softkeyboard-with-showsoftinput-is-not-working + findOnPageEditText.postDelayed(() -> { + // Set the focus on `findOnPageEditText`. + findOnPageEditText.requestFocus(); + + // Display the keyboard. `0` sets no input flags. + inputMethodManager.showSoftInput(findOnPageEditText, 0); + }, 200); + return true; + + case R.id.add_to_homescreen: + // Show the alert dialog. + AppCompatDialogFragment createHomeScreenShortcutDialogFragment = new CreateHomeScreenShortcutDialog(); + createHomeScreenShortcutDialogFragment.show(getSupportFragmentManager(), getString(R.string.create_shortcut)); + + //Everything else will be handled by the alert dialog and the associated listener below. + return true; + case R.id.view_source: // Launch the View Source activity. Intent viewSourceIntent = new Intent(this, ViewSourceActivity.class); startActivity(viewSourceIntent); return true; - case R.id.proxy_through_orbot: - // Toggle the proxy through Orbot variable. - proxyThroughOrbot = !proxyThroughOrbot; - - // Apply the proxy through Orbot settings. - applyProxyThroughOrbot(true); - return true; - - case R.id.share: + case R.id.share_url: // Setup the share string. String shareString = webViewTitle + " – " + urlTextBox.getText().toString(); @@ -2876,33 +2905,43 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook shareIntent.setType("text/plain"); // Make it so. - startActivity(Intent.createChooser(shareIntent, "Share URL")); + startActivity(Intent.createChooser(shareIntent, getString(R.string.share_url))); return true; - case R.id.find_on_page: - // Hide the URL app bar. - supportAppBar.setVisibility(View.GONE); + case R.id.open_with_app: + // Create the open with intent with `ACTION_VIEW`. + Intent openWithAppIntent = new Intent(Intent.ACTION_VIEW); - // Show the Find on Page `RelativeLayout`. - findOnPageLinearLayout.setVisibility(View.VISIBLE); + // Set the URI but not the MIME type. This should open all available apps. + openWithAppIntent.setData(Uri.parse(formattedUrlString)); - // Display the keyboard. We have to wait 200 ms before running the command to work around a bug in Android. - // http://stackoverflow.com/questions/5520085/android-show-softkeyboard-with-showsoftinput-is-not-working - findOnPageEditText.postDelayed(() -> { - // Set the focus on `findOnPageEditText`. - findOnPageEditText.requestFocus(); + // Flag the intent to open in a new task. + openWithAppIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - // Display the keyboard. `0` sets no input flags. - inputMethodManager.showSoftInput(findOnPageEditText, 0); - }, 200); + // Show the chooser. + startActivity(Intent.createChooser(openWithAppIntent, getString(R.string.open_with))); return true; - case R.id.add_to_homescreen: - // Show the `CreateHomeScreenShortcutDialog` `AlertDialog` and name this instance `R.string.create_shortcut`. - AppCompatDialogFragment createHomeScreenShortcutDialogFragment = new CreateHomeScreenShortcutDialog(); - createHomeScreenShortcutDialogFragment.show(getSupportFragmentManager(), getString(R.string.create_shortcut)); + case R.id.open_with_browser: + // Create the open with intent with `ACTION_VIEW`. + Intent openWithBrowserIntent = new Intent(Intent.ACTION_VIEW); + + // Set the URI and the MIME type. `"text/html"` should load browser options. + openWithBrowserIntent.setDataAndType(Uri.parse(formattedUrlString), "text/html"); + + // Flag the intent to open in a new task. + openWithBrowserIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + + // Show the chooser. + startActivity(Intent.createChooser(openWithBrowserIntent, getString(R.string.open_with))); + return true; + + case R.id.proxy_through_orbot: + // Toggle the proxy through Orbot variable. + proxyThroughOrbot = !proxyThroughOrbot; - //Everything else will be handled by `CreateHomeScreenShortcutDialog` and the associated listener below. + // Apply the proxy through Orbot settings. + applyProxyThroughOrbot(true); return true; case R.id.refresh: @@ -3170,7 +3209,19 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); - // Reload the ad for the free flavor if we not in full screen mode. + // Get the status bar pixel size. + int statusBarResourceId = getResources().getIdentifier("status_bar_height", "dimen", "android"); + int statusBarPixelSize = getResources().getDimensionPixelSize(statusBarResourceId); + + // Get the resource density. + float screenDensity = getResources().getDisplayMetrics().density; + + // Recalculate the drawer header padding. + drawerHeaderPaddingLeftAndRight = (int) (15 * screenDensity); + drawerHeaderPaddingTop = statusBarPixelSize + (int) (4 * screenDensity); + drawerHeaderPaddingBottom = (int) (8 * screenDensity); + + // Reload the ad for the free flavor if not in full screen mode. if (BuildConfig.FLAVOR.contentEquals("free") && !inFullScreenBrowsingMode) { // Reload the ad. The AdView is destroyed and recreated, which changes the ID, every time it is reloaded to handle possible rotations. AdHelper.loadAd(findViewById(R.id.adview), getApplicationContext(), getString(R.string.ad_unit_id)); @@ -3443,8 +3494,8 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Create the bookmark. bookmarksDatabaseHelper.createBookmark(bookmarkNameString, bookmarkUrlString, currentBookmarksFolder, newBookmarkDisplayOrder, favoriteIconByteArray); - // Update `bookmarksCursor` with the current contents of this folder. - bookmarksCursor = bookmarksDatabaseHelper.getAllBookmarksCursorByDisplayOrder(currentBookmarksFolder); + // Update the bookmarks cursor with the current contents of this folder. + bookmarksCursor = bookmarksDatabaseHelper.getBookmarksByDisplayOrder(currentBookmarksFolder); // Update the `ListView`. bookmarksCursorAdapter.changeCursor(bookmarksCursor); @@ -3488,8 +3539,8 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Create the folder, which will be placed at the top of the `ListView`. bookmarksDatabaseHelper.createFolder(folderNameString, currentBookmarksFolder, folderIconByteArray); - // Update `bookmarksCursor` with the current contents of this folder. - bookmarksCursor = bookmarksDatabaseHelper.getAllBookmarksCursorByDisplayOrder(currentBookmarksFolder); + // Update the bookmarks cursor with the current contents of this folder. + bookmarksCursor = bookmarksDatabaseHelper.getBookmarksByDisplayOrder(currentBookmarksFolder); // Update the `ListView`. bookmarksCursorAdapter.changeCursor(bookmarksCursor); @@ -3703,8 +3754,8 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook bookmarksDatabaseHelper.updateBookmark(selectedBookmarkDatabaseId, bookmarkNameString, bookmarkUrlString, newFavoriteIconByteArray); } - // Update `bookmarksCursor` with the current contents of this folder. - bookmarksCursor = bookmarksDatabaseHelper.getAllBookmarksCursorByDisplayOrder(currentBookmarksFolder); + // Update the bookmarks cursor with the current contents of this folder. + bookmarksCursor = bookmarksDatabaseHelper.getBookmarksByDisplayOrder(currentBookmarksFolder); // Update the `ListView`. bookmarksCursorAdapter.changeCursor(bookmarksCursor); @@ -3765,8 +3816,8 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook bookmarksDatabaseHelper.updateFolder(selectedFolderDatabaseId, oldFolderNameString, newFolderNameString, folderIconByteArray); } - // Update `bookmarksCursor` with the current contents of this folder. - bookmarksCursor = bookmarksDatabaseHelper.getAllBookmarksCursorByDisplayOrder(currentBookmarksFolder); + // Update the bookmarks cursor with the current contents of this folder. + bookmarksCursor = bookmarksDatabaseHelper.getBookmarksByDisplayOrder(currentBookmarksFolder); // Update the `ListView`. bookmarksCursorAdapter.changeCursor(bookmarksCursor); @@ -3857,7 +3908,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook drawerLayout.closeDrawer(GravityCompat.END); } else { // A subfolder is displayed. // Place the former parent folder in `currentFolder`. - currentBookmarksFolder = bookmarksDatabaseHelper.getParentFolder(currentBookmarksFolder); + currentBookmarksFolder = bookmarksDatabaseHelper.getParentFolderName(currentBookmarksFolder); // Load the new folder. loadBookmarksFolder(); @@ -4630,7 +4681,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Create a download intent. Not specifying the action type will display the maximum number of options. Intent downloadIntent = new Intent(); - // Set the URI and the mime type. `"*/*"` will display the maximum number of options. + // Set the URI and the MIME type. Specifying `text/html` displays a good number of options. downloadIntent.setDataAndType(Uri.parse(url), "text/html"); // Flag the intent to open in a new task. @@ -4700,7 +4751,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook private void loadBookmarksFolder() { // Update the bookmarks cursor with the contents of the bookmarks database for the current folder. - bookmarksCursor = bookmarksDatabaseHelper.getAllBookmarksCursorByDisplayOrder(currentBookmarksFolder); + bookmarksCursor = bookmarksDatabaseHelper.getBookmarksByDisplayOrder(currentBookmarksFolder); // Populate the bookmarks cursor adapter. `this` specifies the `Context`. `false` disables `autoRequery`. bookmarksCursorAdapter = new CursorAdapter(this, bookmarksCursor, false) {