X-Git-Url: https://gitweb.stoutner.com/?a=blobdiff_plain;f=app%2Fsrc%2Fmain%2Fjava%2Fcom%2Fstoutner%2Fprivacybrowser%2Factivities%2FMainWebView.java;h=345a7060a99a1addc522b33f4c8e8c1782b21794;hb=f53f9266d055030230e9fc55a7a921891bfd384c;hp=c7e987c116337b57012646976f690e2f43266160;hpb=a56ffa22c6a0ef7ad717cba03a433999553340cb;p=PrivacyBrowserAndroid.git diff --git a/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebView.java b/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebView.java index c7e987c1..345a7060 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebView.java +++ b/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebView.java @@ -22,6 +22,8 @@ package com.stoutner.privacybrowser.activities; import android.annotation.SuppressLint; import android.app.DialogFragment; import android.app.DownloadManager; +import android.content.ClipData; +import android.content.ClipboardManager; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; @@ -103,7 +105,7 @@ public class MainWebView extends AppCompatActivity implements NavigationView.OnN SslCertificateError.SslCertificateErrorListener, DownloadFile.DownloadFileListener, DownloadImage.DownloadImageListener, UrlHistory.UrlHistoryListener { // `appBar` is public static so it can be accessed from `OrbotProxyHelper`. - // It is also used in `onCreate()`, `onOptionsItemSelected()`, and `closeFindOnPage()`. + // It is also used in `onCreate()`, `onOptionsItemSelected()`, `closeFindOnPage()`, and `applySettings()`. public static ActionBar appBar; // `favoriteIcon` is public static so it can be accessed from `CreateHomeScreenShortcut`, `Bookmarks`, `CreateBookmark`, `CreateBookmarkFolder`, and `EditBookmark`. @@ -128,6 +130,9 @@ public class MainWebView extends AppCompatActivity implements NavigationView.OnN // 'mainWebView' is used in `onCreate()`, `onOptionsItemSelected()`, `onNavigationItemSelected()`, `onRestart()`, `onCreateContextMenu()`, `findPreviousOnPage()`, `findNextOnPage()`, `closeFindOnPage()`, and `loadUrlFromTextBox()`. private WebView mainWebView; + // `fullScreenVideoFrameLayout` is used in `onCreate()` and `onConfigurationChanged()`. + private FrameLayout fullScreenVideoFrameLayout; + // `swipeRefreshLayout` is used in `onCreate()`, `onPrepareOptionsMenu`, and `onRestart()`. private SwipeRefreshLayout swipeRefreshLayout; @@ -165,18 +170,33 @@ public class MainWebView extends AppCompatActivity implements NavigationView.OnN // `javaScriptEnabledSearchURL` is used in `loadURLFromTextBox()` and `applySettings()`. private String javaScriptEnabledSearchURL; + // `fullScreenBrowsingModeEnabled` is used in `onCreate()` and `applySettings()`. + private boolean fullScreenBrowsingModeEnabled; + + // `inFullScreenBrowsingMode` is used in `onCreate()` and `applySettings()`. + private boolean inFullScreenBrowsingMode; + // `hideSystemBarsOnFullscreen` is used in `onCreate()` and `applySettings()`. private boolean hideSystemBarsOnFullscreen; // `translucentNavigationBarOnFullscreen` is used in `onCreate()` and `applySettings()`. private boolean translucentNavigationBarOnFullscreen; + // `findOnPageLinearLayout` is used in `onCreate()`, `onOptionsItemSelected()`, and `closeFindOnPage()`. + private LinearLayout findOnPageLinearLayout; + + // `findOnPageEditText` is used in `onCreate()`, `onOptionsItemSelected()`, and `closeFindOnPage()`. + private EditText findOnPageEditText; + // `mainMenu` is used in `onCreateOptionsMenu()` and `updatePrivacyIcons()`. private Menu mainMenu; // `drawerToggle` is used in `onCreate()`, `onPostCreate()`, `onConfigurationChanged()`, `onNewIntent()`, and `onNavigationItemSelected()`. private ActionBarDrawerToggle drawerToggle; + // `supportAppBar` is used in `onCreate()`, `onOptionsItemSelected()`, and `closeFindOnPage()`. + private Toolbar supportAppBar; + // `urlTextBox` is used in `onCreate()`, `onOptionsItemSelected()`, and `loadUrlFromTextBox()`. private EditText urlTextBox; @@ -186,9 +206,6 @@ public class MainWebView extends AppCompatActivity implements NavigationView.OnN // `sslErrorHandler` is used in `onCreate()`, `onSslErrorCancel()`, and `onSslErrorProceed`. private SslErrorHandler sslErrorHandler; - // `findOnPageEditText` is used in `onCreate()`, `onOptionsItemSelected()`, and `closeFindOnPage()`. - private EditText findOnPageEditText; - // `inputMethodManager` is used in `onOptionsItemSelected()`, `loadUrlFromTextBox()`, and `closeFindOnPage()`. private InputMethodManager inputMethodManager; @@ -203,7 +220,7 @@ public class MainWebView extends AppCompatActivity implements NavigationView.OnN inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); // We need to use the `SupportActionBar` from `android.support.v7.app.ActionBar` until the minimum API is >= 21. - Toolbar supportAppBar = (Toolbar) findViewById(R.id.app_bar); + supportAppBar = (Toolbar) findViewById(R.id.app_bar); setSupportActionBar(supportAppBar); appBar = getSupportActionBar(); @@ -240,76 +257,84 @@ public class MainWebView extends AppCompatActivity implements NavigationView.OnN drawerLayout = (DrawerLayout) findViewById(R.id.drawerlayout); rootCoordinatorLayout = (CoordinatorLayout) findViewById(R.id.root_coordinatorlayout); mainWebView = (WebView) findViewById(R.id.mainWebView); + findOnPageLinearLayout = (LinearLayout) findViewById(R.id.find_on_page_linearlayout); findOnPageEditText = (EditText) findViewById(R.id.find_on_page_edittext); - final FrameLayout fullScreenVideoFrameLayout = (FrameLayout) findViewById(R.id.full_screen_video_framelayout); + fullScreenVideoFrameLayout = (FrameLayout) findViewById(R.id.full_screen_video_framelayout); // Create a double-tap listener to toggle full-screen mode. final GestureDetector gestureDetector = new GestureDetector(this, new GestureDetector.SimpleOnGestureListener() { // Override `onDoubleTap()`. All other events are handled using the default settings. @Override public boolean onDoubleTap(MotionEvent event) { - if (appBar.isShowing()) { // If `appBar` is visible, switch to full screen mode. - // Hide the `appBar`. - appBar.hide(); + if (fullScreenBrowsingModeEnabled) { // Only process the double-tap if full screen browsing mode is enabled. + // Toggle `inFullScreenBrowsingMode`. + inFullScreenBrowsingMode = !inFullScreenBrowsingMode; - // Hide the `BannerAd` in the free flavor. - if (BuildConfig.FLAVOR.contentEquals("free")) { - BannerAd.hideAd(adView); - } + if (inFullScreenBrowsingMode) { // Switch to full screen mode. + // Hide the `appBar`. + appBar.hide(); + + // Hide the `BannerAd` in the free flavor. + if (BuildConfig.FLAVOR.contentEquals("free")) { + BannerAd.hideAd(adView); + } - // Modify the system bars. - if (hideSystemBarsOnFullscreen) { // Hide everything. - // Remove the translucent overlays. - getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); + // Modify the system bars. + if (hideSystemBarsOnFullscreen) { // Hide everything. + // Remove the translucent overlays. + getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); - // Remove the translucent status bar overlay on the `Drawer Layout`, which is special and needs its own command. - drawerLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN); + // Remove the translucent status bar overlay on the `Drawer Layout`, which is special and needs its own command. + drawerLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN); /* SYSTEM_UI_FLAG_FULLSCREEN hides the status bar at the top of the screen. * SYSTEM_UI_FLAG_HIDE_NAVIGATION hides the navigation bar on the bottom or right of the screen. * SYSTEM_UI_FLAG_IMMERSIVE_STICKY makes the status and navigation bars translucent and automatically rehides them after they are shown. */ - rootCoordinatorLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY); + rootCoordinatorLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY); + + // Set `rootCoordinatorLayout` to fill the whole screen. + rootCoordinatorLayout.setFitsSystemWindows(false); + } else { // Hide everything except the status and navigation bars. + // Set `rootCoordinatorLayout` to fit under the status and navigation bars. + rootCoordinatorLayout.setFitsSystemWindows(false); + + if (translucentNavigationBarOnFullscreen) { // There is an Android Support Library bug that causes a scrim to print on the right side of the `Drawer Layout` when the navigation bar is displayed on the right of the screen. + // Set the navigation bar to be translucent. + getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION); + } + } + } else { // Switch to normal viewing mode. + // Show the `appBar`. + appBar.show(); - // Set `rootCoordinatorLayout` to fill the whole screen. - rootCoordinatorLayout.setFitsSystemWindows(false); - } else { // Hide everything except the status and navigation bars. - // Set `rootCoordinatorLayout` to fit under the status and navigation bars. - rootCoordinatorLayout.setFitsSystemWindows(false); + // Show the `BannerAd` in the free flavor. + if (BuildConfig.FLAVOR.contentEquals("free")) { + // Reload the ad. Because the screen may have rotated, we need to use `reloadAfterRotate`. + BannerAd.reloadAfterRotate(adView, getApplicationContext(), getString(R.string.ad_id)); - if (translucentNavigationBarOnFullscreen) { // There is an Android Support Library bug that causes an ugly scrim to print on the `Drawer Layout` when the navigation bar is displayed on the right of the screen. - // Set the navigation bar to be translucent. - getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION); + // Reinitialize the `adView` variable, as the `View` will have been removed and re-added by `BannerAd.reloadAfterRotate()`. + adView = findViewById(R.id.adView); } - } - } else { // Switch to normal viewing mode. - // Show the `appBar`. - appBar.show(); - // Show the `BannerAd` in the free flavor. - if (BuildConfig.FLAVOR.contentEquals("free")) { - // Reload the ad. Because the screen may have rotated, we need to use `reloadAfterRotate`. - BannerAd.reloadAfterRotate(adView, getApplicationContext(), getString(R.string.ad_id)); + // Remove the translucent navigation bar flag if it is set. + getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION); - // Reinitialize the `adView` variable, as the `View` will have been removed and re-added by `BannerAd.reloadAfterRotate()`. - adView = findViewById(R.id.adView); - } - - // Remove the translucent navigation bar flag if it is set. - getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION); + // Add the translucent status flag if it is unset. This also resets `drawerLayout's` `View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN`. + getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); - // Add the translucent status flag if it is unset. This also resets `drawerLayout's` `View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN`. - getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); + // Remove any `SYSTEM_UI` flags from `rootCoordinatorLayout`. + rootCoordinatorLayout.setSystemUiVisibility(0); - // Remove any `SYSTEM_UI` flags from `rootCoordinatorLayout`. - rootCoordinatorLayout.setSystemUiVisibility(0); + // Constrain `rootCoordinatorLayout` inside the status and navigation bars. + rootCoordinatorLayout.setFitsSystemWindows(true); + } - // Constrain `rootCoordinatorLayout` inside the status and navigation bars. - rootCoordinatorLayout.setFitsSystemWindows(true); + // Consume the double-tap. + return true; + } else { // Do not consume the double-tap because full screen browsing mode is disabled. + return false; } - - // Consume the double-tap. - return true; } }); @@ -428,7 +453,7 @@ public class MainWebView extends AppCompatActivity implements NavigationView.OnN }); // drawerToggle creates the hamburger icon at the start of the AppBar. - drawerToggle = new ActionBarDrawerToggle(this, drawerLayout, supportAppBar, R.string.open_navigation, R.string.close_navigation); + drawerToggle = new ActionBarDrawerToggle(this, drawerLayout, supportAppBar, R.string.open_navigation_drawer, R.string.close_navigation_drawer); mainWebView.setWebViewClient(new WebViewClient() { // `shouldOverrideUrlLoading` makes this `WebView` the default handler for URLs inside the app, so that links are not kicked out to other apps. @@ -436,7 +461,7 @@ public class MainWebView extends AppCompatActivity implements NavigationView.OnN @SuppressWarnings("deprecation") @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { - // Use an external email program if the link begins with "mailto:". + // Use an external email program if the link begins with `mailto:`. if (url.startsWith("mailto:")) { // We use `ACTION_SENDTO` instead of `ACTION_SEND` so that only email programs are launched. Intent emailIntent = new Intent(Intent.ACTION_SENDTO); @@ -522,42 +547,51 @@ public class MainWebView extends AppCompatActivity implements NavigationView.OnN // Enter full screen video @Override public void onShowCustomView(View view, CustomViewCallback callback) { - appBar.hide(); - - // Show the fullScreenVideoFrameLayout. - fullScreenVideoFrameLayout.addView(view); - fullScreenVideoFrameLayout.setVisibility(View.VISIBLE); - - // Hide the mainWebView. - mainWebView.setVisibility(View.GONE); - - // Hide the ad if this is the free flavor. + // Pause the ad if this is the free flavor. if (BuildConfig.FLAVOR.contentEquals("free")) { - BannerAd.hideAd(adView); + BannerAd.pauseAd(adView); } + // Remove the translucent overlays. + getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); + + // Remove the translucent status bar overlay on the `Drawer Layout`, which is special and needs its own command. + drawerLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN); + /* SYSTEM_UI_FLAG_FULLSCREEN hides the status bar at the top of the screen. * SYSTEM_UI_FLAG_HIDE_NAVIGATION hides the navigation bar on the bottom or right of the screen. * SYSTEM_UI_FLAG_IMMERSIVE_STICKY makes the status and navigation bars translucent and automatically rehides them after they are shown. */ - view.setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY); + rootCoordinatorLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY); + + // Set `rootCoordinatorLayout` to fill the entire screen. + rootCoordinatorLayout.setFitsSystemWindows(false); + + // Add `view` to `fullScreenVideoFrameLayout` and display it on the screen. + fullScreenVideoFrameLayout.addView(view); + fullScreenVideoFrameLayout.setVisibility(View.VISIBLE); } // Exit full screen video public void onHideCustomView() { - appBar.show(); + // Hide `fullScreenVideoFrameLayout`. + fullScreenVideoFrameLayout.removeAllViews(); + fullScreenVideoFrameLayout.setVisibility(View.GONE); - // Show the mainWebView. - mainWebView.setVisibility(View.VISIBLE); + // Add the translucent status flag. This also resets `drawerLayout's` `View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN`. + getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); + + // Set `rootCoordinatorLayout` to fit inside the status and navigation bars. This also clears the `SYSTEM_UI` flags. + rootCoordinatorLayout.setFitsSystemWindows(true); // Show the ad if this is the free flavor. if (BuildConfig.FLAVOR.contentEquals("free")) { - BannerAd.showAd(adView); - } + // Reload the ad. Because the screen may have rotated, we need to use `reloadAfterRotate`. + BannerAd.reloadAfterRotate(adView, getApplicationContext(), getString(R.string.ad_id)); - // Hide the fullScreenVideoFrameLayout. - fullScreenVideoFrameLayout.removeAllViews(); - fullScreenVideoFrameLayout.setVisibility(View.GONE); + // Reinitialize the `adView` variable, as the `View` will have been removed and re-added by `BannerAd.reloadAfterRotate()`. + adView = findViewById(R.id.adView); + } } }); @@ -586,7 +620,7 @@ public class MainWebView extends AppCompatActivity implements NavigationView.OnN // Replace the header that `WebView` creates for `X-Requested-With` with a null value. The default value is the application ID (com.stoutner.privacybrowser.standard). customHeaders.put("X-Requested-With", ""); - // Initialize the default preference values the first time the program is run. + // Initialize the default preference values the first time the program is run. `this` is the context. `false` keeps this command from resetting any current preferences back to default. PreferenceManager.setDefaultValues(this, R.xml.preferences, false); // Apply the settings from the shared preferences. @@ -617,6 +651,9 @@ public class MainWebView extends AppCompatActivity implements NavigationView.OnN favoriteIcon = favoriteIconBitmapDrawable.getBitmap(); } + // Initialize `inFullScreenBrowsingMode`, which is always false at this point because Privacy Browser never starts in full screen browsing mode. + inFullScreenBrowsingMode = false; + // Initialize AdView for the free flavor and request an ad. If this is not the free flavor BannerAd.requestAd() does nothing. adView = findViewById(R.id.adView); BannerAd.requestAd(adView); @@ -924,7 +961,7 @@ public class MainWebView extends AppCompatActivity implements NavigationView.OnN case R.id.clearFormData: WebViewDatabase mainWebViewDatabase = WebViewDatabase.getInstance(this); mainWebViewDatabase.clearFormData(); - mainWebView.reload(); + Snackbar.make(findViewById(R.id.mainWebView), R.string.form_data_deleted, Snackbar.LENGTH_SHORT).show(); return true; case R.id.fontSizeFiftyPercent: @@ -957,11 +994,9 @@ public class MainWebView extends AppCompatActivity implements NavigationView.OnN case R.id.find_on_page: // Hide the URL app bar. - Toolbar appBarToolbar = (Toolbar) findViewById(R.id.app_bar); - appBarToolbar.setVisibility(View.GONE); + supportAppBar.setVisibility(View.GONE); // Show the Find on Page `RelativeLayout`. - LinearLayout findOnPageLinearLayout = (LinearLayout) findViewById(R.id.find_on_page_linearlayout); findOnPageLinearLayout.setVisibility(View.VISIBLE); // Display the keyboard. We have to wait 200 ms before running the command to work around a bug in Android. @@ -1096,8 +1131,8 @@ public class MainWebView extends AppCompatActivity implements NavigationView.OnN domStorage.deleteAllData(); // Clear form data. - WebViewDatabase formData = WebViewDatabase.getInstance(this); - formData.clearFormData(); + WebViewDatabase webViewDatabase = WebViewDatabase.getInstance(this); + webViewDatabase.clearFormData(); // Clear cache. The argument of "true" includes disk files. mainWebView.clearCache(true); @@ -1153,16 +1188,13 @@ public class MainWebView extends AppCompatActivity implements NavigationView.OnN public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); - // Handle the `adView` for the free version. - if (BuildConfig.FLAVOR.contentEquals("free")) { - // Reload the add if we are not in full screen mode. - if (adView.isShown()) { - // Reload the ad. - BannerAd.reloadAfterRotate(adView, getApplicationContext(), getString(R.string.ad_id)); + // Reload the ad for the free flavor if we are not in full screen mode. + if (BuildConfig.FLAVOR.contentEquals("free") && adView.isShown() && !fullScreenVideoFrameLayout.isShown()) { + // Reload the ad. + BannerAd.reloadAfterRotate(adView, getApplicationContext(), getString(R.string.ad_id)); - // Reinitialize the `adView` variable, as the `View` will have been removed and re-added by `BannerAd.reloadAfterRotate()`. - adView = findViewById(R.id.adView); - } + // Reinitialize the `adView` variable, as the `View` will have been removed and re-added by `BannerAd.reloadAfterRotate()`. + adView = findViewById(R.id.adView); } // `invalidateOptionsMenu` should recalculate the number of action buttons from the menu to display on the app bar, but it doesn't because of the this bug: https://code.google.com/p/android/issues/detail?id=20493#c8 @@ -1178,6 +1210,9 @@ public class MainWebView extends AppCompatActivity implements NavigationView.OnN final String imageUrl; final String linkUrl; + // Get a handle for the `ClipboardManager`. + final ClipboardManager clipboardManager = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE); + switch (hitTestResult.getType()) { // `SRC_ANCHOR_TYPE` is a link. case WebView.HitTestResult.SRC_ANCHOR_TYPE: @@ -1187,7 +1222,7 @@ public class MainWebView extends AppCompatActivity implements NavigationView.OnN // Set the target URL as the title of the `ContextMenu`. menu.setHeaderTitle(linkUrl); - // Add a `Load URL` button. + // Add a `Load URL` entry. menu.add(R.string.load_url).setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() { @Override public boolean onMenuItemClick(MenuItem item) { @@ -1196,7 +1231,20 @@ public class MainWebView extends AppCompatActivity implements NavigationView.OnN } }); - // Add a `Cancel` button, which by default closes the `ContextMenu`. + // Add a `Copy URL` entry. + menu.add(R.string.copy_url).setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() { + @Override + public boolean onMenuItemClick(MenuItem item) { + // Save the link URL in a `ClipData`. + ClipData srcAnchorTypeClipData = ClipData.newPlainText(getResources().getString(R.string.url), linkUrl); + + // Set the `ClipData` as the clipboard's primary clip. + clipboardManager.setPrimaryClip(srcAnchorTypeClipData); + return false; + } + }); + + // Add a `Cancel` entry, which by default closes the `ContextMenu`. menu.add(R.string.cancel); break; @@ -1207,7 +1255,7 @@ public class MainWebView extends AppCompatActivity implements NavigationView.OnN // Set the target URL as the title of the `ContextMenu`. menu.setHeaderTitle(linkUrl); - // Add a `Write Email` button. + // Add a `Write Email` entry. menu.add(R.string.write_email).setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() { @Override public boolean onMenuItemClick(MenuItem item) { @@ -1226,7 +1274,20 @@ public class MainWebView extends AppCompatActivity implements NavigationView.OnN } }); - // Add a `Cancel` button, which by default closes the `ContextMenu`. + // Add a `Copy Email Address` entry. + menu.add(R.string.copy_email_address).setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() { + @Override + public boolean onMenuItemClick(MenuItem item) { + // Save the email address in a `ClipData`. + ClipData srcEmailTypeClipData = ClipData.newPlainText(getResources().getString(R.string.email_address), linkUrl); + + // Set the `ClipData` as the clipboard's primary clip. + clipboardManager.setPrimaryClip(srcEmailTypeClipData); + return false; + } + }); + + // Add a `Cancel` entry, which by default closes the `ContextMenu`. menu.add(R.string.cancel); break; @@ -1238,7 +1299,7 @@ public class MainWebView extends AppCompatActivity implements NavigationView.OnN // Set the image URL as the title of the `ContextMenu`. menu.setHeaderTitle(imageUrl); - // Add a `View Image` button. + // Add a `View Image` entry. menu.add(R.string.view_image).setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() { @Override public boolean onMenuItemClick(MenuItem item) { @@ -1247,7 +1308,7 @@ public class MainWebView extends AppCompatActivity implements NavigationView.OnN } }); - // Add a `Download Image` button. + // Add a `Download Image` entry. menu.add(R.string.download_image).setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() { @Override public boolean onMenuItemClick(MenuItem item) { @@ -1258,7 +1319,20 @@ public class MainWebView extends AppCompatActivity implements NavigationView.OnN } }); - // Add a `Cancel` button, which by default closes the `ContextMenu`. + // Add a `Copy URL` entry. + menu.add(R.string.copy_url).setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() { + @Override + public boolean onMenuItemClick(MenuItem item) { + // Save the image URL in a `ClipData`. + ClipData srcImageTypeClipData = ClipData.newPlainText(getResources().getString(R.string.url), imageUrl); + + // Set the `ClipData` as the clipboard's primary clip. + clipboardManager.setPrimaryClip(srcImageTypeClipData); + return false; + } + }); + + // Add a `Cancel` entry, which by default closes the `ContextMenu`. menu.add(R.string.cancel); break; @@ -1271,7 +1345,7 @@ public class MainWebView extends AppCompatActivity implements NavigationView.OnN // Set the image URL as the title of the `ContextMenu`. menu.setHeaderTitle(imageUrl); - // Add a `View Image` button. + // Add a `View Image` entry. menu.add(R.string.view_image).setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() { @Override public boolean onMenuItemClick(MenuItem item) { @@ -1280,7 +1354,7 @@ public class MainWebView extends AppCompatActivity implements NavigationView.OnN } }); - // Add a `Download Image` button. + // Add a `Download Image` entry. menu.add(R.string.download_image).setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() { @Override public boolean onMenuItemClick(MenuItem item) { @@ -1291,7 +1365,20 @@ public class MainWebView extends AppCompatActivity implements NavigationView.OnN } }); - // Add a `Cancel` button, which by default closes the `ContextMenu`. + // Add a `Copy URL` entry. + menu.add(R.string.copy_url).setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() { + @Override + public boolean onMenuItemClick(MenuItem item) { + // Save the image URL in a `ClipData`. + ClipData srcImageAnchorTypeClipData = ClipData.newPlainText(getResources().getString(R.string.url), imageUrl); + + // Set the `ClipData` as the clipboard's primary clip. + clipboardManager.setPrimaryClip(srcImageAnchorTypeClipData); + return false; + } + }); + + // Add a `Cancel` entry, which by default closes the `ContextMenu`. menu.add(R.string.cancel); break; } @@ -1408,11 +1495,9 @@ public class MainWebView extends AppCompatActivity implements NavigationView.OnN mainWebView.clearHistory(); } - // Override onBackPressed to handle the navigation drawer and mainWebView. + // Override `onBackPressed` to handle the navigation drawer and `mainWebView`. @Override public void onBackPressed() { - final WebView mainWebView = (WebView) findViewById(R.id.mainWebView); - // Close the navigation drawer if it is available. GravityCompat.START is the drawer on the left on Left-to-Right layout text. if (drawerLayout.isDrawerVisible(GravityCompat.START)) { drawerLayout.closeDrawer(GravityCompat.START); @@ -1421,7 +1506,7 @@ public class MainWebView extends AppCompatActivity implements NavigationView.OnN if (mainWebView.canGoBack()) { mainWebView.goBack(); } else { - // Pass onBackPressed to the system. + // Pass `onBackPressed()` to the system. super.onBackPressed(); } } @@ -1537,12 +1622,10 @@ public class MainWebView extends AppCompatActivity implements NavigationView.OnN mainWebView.clearMatches(); // Hide the Find on Page `RelativeLayout`. - LinearLayout findOnPageLinearLayout = (LinearLayout) findViewById(R.id.find_on_page_linearlayout); findOnPageLinearLayout.setVisibility(View.GONE); // Show the URL app bar. - Toolbar appBarToolbar = (Toolbar) findViewById(R.id.app_bar); - appBarToolbar.setVisibility(View.VISIBLE); + supportAppBar.setVisibility(View.VISIBLE); // Hide the keyboard so we can see the webpage. `0` indicates no additional flags. inputMethodManager.hideSoftInputFromWindow(mainWebView.getWindowToken(), 0); @@ -1553,7 +1636,7 @@ public class MainWebView extends AppCompatActivity implements NavigationView.OnN SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this); // Store the values from `sharedPreferences` in variables. - String userAgentString = sharedPreferences.getString("user_agent", "Default user agent"); + String userAgentString = sharedPreferences.getString("user_agent", "PrivacyBrowser/1.0"); String customUserAgentString = sharedPreferences.getString("custom_user_agent", "PrivacyBrowser/1.0"); String javaScriptDisabledSearchString = sharedPreferences.getString("javascript_disabled_search", "https://duckduckgo.com/html/?q="); String javaScriptDisabledCustomSearchString = sharedPreferences.getString("javascript_disabled_search_custom_url", ""); @@ -1564,6 +1647,7 @@ public class MainWebView extends AppCompatActivity implements NavigationView.OnN swipeToRefreshEnabled = sharedPreferences.getBoolean("swipe_to_refresh_enabled", false); boolean doNotTrackEnabled = sharedPreferences.getBoolean("do_not_track", true); boolean proxyThroughOrbot = sharedPreferences.getBoolean("proxy_through_orbot", false); + fullScreenBrowsingModeEnabled = sharedPreferences.getBoolean("enable_full_screen_browsing_mode", false); hideSystemBarsOnFullscreen = sharedPreferences.getBoolean("hide_system_bars", false); translucentNavigationBarOnFullscreen = sharedPreferences.getBoolean("translucent_navigation_bar", true); @@ -1641,7 +1725,7 @@ public class MainWebView extends AppCompatActivity implements NavigationView.OnN } // If we are in full screen mode update the `SYSTEM_UI` flags. - if (!appBar.isShowing()) { + if (inFullScreenBrowsingMode) { if (hideSystemBarsOnFullscreen) { // Hide everything. // Remove the translucent navigation setting if it is currently flagged. getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);