]> gitweb.stoutner.com Git - PrivacyBrowserAndroid.git/blobdiff - app/src/main/java/com/stoutner/privacybrowser/Webview.java
Create Clear Dom Storage and Exit menu items and set launchMode="SingleTask".
[PrivacyBrowserAndroid.git] / app / src / main / java / com / stoutner / privacybrowser / Webview.java
index 5f1e87239a5a009f22d67723638928c8f7aed975..53311f7adb6f5c51e9c8a86193a74ee2e4d3bc2f 100644 (file)
@@ -1,3 +1,22 @@
+/**
+ * Copyright 2015-2016 Soren Stoutner <soren@stoutner.com>.
+ *
+ * This file is part of Privacy Browser.
+ *
+ * Privacy Browser is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Privacy Browser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Privacy Browser.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
 package com.stoutner.privacybrowser;
 
 import android.annotation.SuppressLint;
@@ -12,50 +31,73 @@ import android.graphics.Bitmap;
 import android.net.Uri;
 import android.os.Build;
 import android.os.Bundle;
+import android.support.v4.app.DialogFragment;
 import android.support.v7.app.ActionBar;
 import android.support.v7.app.AppCompatActivity;
+import android.support.v7.app.AppCompatDialogFragment;
 import android.util.Patterns;
 import android.view.KeyEvent;
 import android.view.Menu;
 import android.view.MenuItem;
 import android.view.View;
 import android.view.inputmethod.InputMethodManager;
+import android.webkit.CookieManager;
 import android.webkit.DownloadListener;
 import android.webkit.WebChromeClient;
-import android.webkit.WebResourceError;
-import android.webkit.WebResourceRequest;
+import android.webkit.WebStorage;
 import android.webkit.WebView;
 import android.webkit.WebViewClient;
 import android.widget.EditText;
 import android.widget.FrameLayout;
 import android.widget.ImageView;
 import android.widget.ProgressBar;
-import android.widget.RelativeLayout;
 import android.widget.Toast;
 import java.io.UnsupportedEncodingException;
 import java.net.MalformedURLException;
 import java.net.URL;
 import java.net.URLEncoder;
 
-public class Webview extends AppCompatActivity {
+public class Webview extends AppCompatActivity implements CreateHomeScreenShortcut.CreateHomeScreenSchortcutListener {
+    // favoriteIcon is public static so it can be accessed from CreateHomeScreenShortcut.
+    public static Bitmap favoriteIcon;
 
+    // mainWebView is used in onCreate and onOptionsItemSelected.
+    private WebView mainWebView;
+    // formattedUrlString is used in onCreate, onOptionsItemSelected, onCreateHomeScreenShortcutCreate, and loadUrlFromTextBox.
     private String formattedUrlString;
+    // homepage is used in onCreate and onOptionsItemSelected.
     private String homepage = "https://www.duckduckgo.com/";
+    // enableJavaScript is used in onCreate, onCreateOptionsMenu, and onOptionsItemSelected.
+    private boolean enableJavaScript;
+    // enableDomStorage is used in onCreate, onCreateOptionsMenu, and onOptionsItemSelected.
+    private boolean enableDomStorage;
 
-    // Remove Android Studio's warning about the dangers of using SetJavaScriptEnabled.
-    @SuppressLint("SetJavaScriptEnabled")
+    /*  enableSaveFormData does nothing until database storage is implemented.
+    // enableSaveFormData is used in onCreate, onCreateOptionsMenu, and onOptionsItemSelected.
+    private boolean enableSaveFormData;
+    */
+
+    // cookieManager is used in onCreate and onOptionsItemSelected.
+    private CookieManager cookieManager;
+    // enableCookies is used in onCreate, onCreateOptionsMenu, and onOptionsItemSelected.
+    private boolean enableCookies;
+
+    // actionBar is used in onCreate and onOptionsItemSelected.
+    private ActionBar actionBar;
 
     @Override
+    // Remove Android Studio's warning about the dangers of using SetJavaScriptEnabled.
+    @SuppressLint("SetJavaScriptEnabled")
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.activity_webview);
 
-        final WebView mainWebView = (WebView) findViewById(R.id.mainWebView);
         final FrameLayout fullScreenVideoFrameLayout = (FrameLayout) findViewById(R.id.fullScreenVideoFrameLayout);
-        final RelativeLayout rootRelativeLayout = (RelativeLayout) findViewById(R.id.rootRelativeLayout);
         final Activity mainWebViewActivity = this;
 
-        final ActionBar actionBar = getSupportActionBar();
+        mainWebView = (WebView) findViewById(R.id.mainWebView);
+        actionBar = getSupportActionBar();
+
         if (actionBar != null) {
             // Remove the title from the action bar.
             actionBar.setDisplayShowTitleEnabled(false);
@@ -69,8 +111,7 @@ public class Webview extends AppCompatActivity {
             urlTextBox.setOnKeyListener(new View.OnKeyListener() {
                 public boolean onKey(View v, int keyCode, KeyEvent event) {
                     // If the event is a key-down event on the "enter" button, load the URL.
-                    if ((event.getAction() == KeyEvent.ACTION_DOWN) &&
-                            (keyCode == KeyEvent.KEYCODE_ENTER)) {
+                    if ((event.getAction() == KeyEvent.ACTION_DOWN) && (keyCode == KeyEvent.KEYCODE_ENTER)) {
                         // Load the URL into the mainWebView and consume the event.
                         try {
                             loadUrlFromTextBox();
@@ -79,9 +120,10 @@ public class Webview extends AppCompatActivity {
                         }
                         // If the enter key was pressed, consume the event.
                         return true;
+                    } else {
+                        // If any other key was pressed, do not consume the event.
+                        return false;
                     }
-                    // If any other key was pressed, do not consume the event.
-                    return false;
                 }
             });
         }
@@ -94,9 +136,11 @@ public class Webview extends AppCompatActivity {
                 return true;
             }
 
+            /* These errors do not provide any useful information and clutter the screen.
             public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
-                Toast.makeText(mainWebViewActivity, "Error loading " + request + "   Error: " + error, Toast.LENGTH_LONG).show();
+                Toast.makeText(mainWebViewActivity, "Error loading " + request + "   Error: " + error, Toast.LENGTH_SHORT).show();
             }
+            */
 
             // Update the URL in urlTextBox when the page starts to load.
             @Override
@@ -138,17 +182,22 @@ public class Webview extends AppCompatActivity {
             // Set the favorite icon when it changes.
             @Override
             public void onReceivedIcon(WebView view, Bitmap icon) {
-                // Make sure that actionBar is not null.
+                // Save a copy of the favorite icon for use if a shortcut is added to the home screen.
+                favoriteIcon = icon;
+
+                // Place the favorite icon in the actionBar if it is not null.
                 if (actionBar != null) {
-                    ImageView favoriteIcon = (ImageView) actionBar.getCustomView().findViewById(R.id.favoriteIcon);
-                    favoriteIcon.setImageBitmap(Bitmap.createScaledBitmap(icon, 64, 64, true));
+                    ImageView imageViewFavoriteIcon = (ImageView) actionBar.getCustomView().findViewById(R.id.favoriteIcon);
+                    imageViewFavoriteIcon.setImageBitmap(Bitmap.createScaledBitmap(icon, 64, 64, true));
                 }
             }
 
             // Enter full screen video
             @Override
             public void onShowCustomView(View view, CustomViewCallback callback) {
-                getSupportActionBar().hide();
+                if (getSupportActionBar() != null) {
+                    getSupportActionBar().hide();
+                }
 
                 fullScreenVideoFrameLayout.addView(view);
                 fullScreenVideoFrameLayout.setVisibility(View.VISIBLE);
@@ -178,7 +227,9 @@ public class Webview extends AppCompatActivity {
 
             // Exit full screen video
             public void onHideCustomView() {
-                getSupportActionBar().show();
+                if (getSupportActionBar() != null) {
+                    getSupportActionBar().show();
+                }
 
                 mainWebView.setVisibility(View.VISIBLE);
 
@@ -187,6 +238,7 @@ public class Webview extends AppCompatActivity {
             }
         });
 
+        // Allow the downloading of files.
         mainWebView.setDownloadListener(new DownloadListener() {
             // Launch the Android download manager when a link leads to a download.
             @Override
@@ -215,11 +267,24 @@ public class Webview extends AppCompatActivity {
             mainWebView.getSettings().setDisplayZoomControls(false);
         }
 
-        // Enable JavaScript.
-        mainWebView.getSettings().setJavaScriptEnabled(true);
+        // Set JavaScript initial status.
+        enableJavaScript = false;
+        mainWebView.getSettings().setJavaScriptEnabled(enableJavaScript);
+
+        // Set DOM Storage initial status.
+        enableDomStorage = false;
+        mainWebView.getSettings().setDomStorageEnabled(enableDomStorage);
+
+        /* Save Form Data does nothing until database storage is implemented.
+        // Set Save Form Data initial status.
+        enableSaveFormData = true;
+        mainWebView.getSettings().setSaveFormData(enableSaveFormData);
+        */
 
-        // Enable DOM Storage.
-        mainWebView.getSettings().setDomStorageEnabled(true);
+        // Set Cookies initial status.
+        enableCookies = false;
+        cookieManager = CookieManager.getInstance();
+        cookieManager.setAcceptCookie(enableCookies);
 
         // Get the intent information that started the app.
         final Intent intent = getIntent();
@@ -239,39 +304,167 @@ public class Webview extends AppCompatActivity {
         mainWebView.loadUrl(formattedUrlString);
     }
 
+    @Override
+    protected void onNewIntent(Intent intent) {
+        // Sets the new intent as the activity intent, so that any future getIntent() picks up this one.
+        setIntent(intent);
+
+        if (intent.getData() != null) {
+            // Get the intent data and convert it to a string.
+            final Uri intentUriData = intent.getData();
+            formattedUrlString = intentUriData.toString();
+        }
+
+        // Load the website.
+        mainWebView.loadUrl(formattedUrlString);
+    }
+
     @Override
     public boolean onCreateOptionsMenu(Menu menu) {
         // Inflate the menu; this adds items to the action bar if it is present.
         getMenuInflater().inflate(R.menu.menu_webview, menu);
+
+        // Get MenuItems for checkable menu items.
+        MenuItem toggleJavaScript = menu.findItem(R.id.toggleJavaScript);
+        MenuItem toggleDomStorage = menu.findItem(R.id.toggleDomStorage);
+        /* toggleSaveFormData does nothing until database storage is implemented.
+        MenuItem toggleSaveFormData = menu.findItem(R.id.toggleSaveFormData);
+        */
+        MenuItem toggleCookies = menu.findItem(R.id.toggleCookies);
+
+        // Set the initial status of the menu item checkboxes.
+        toggleJavaScript.setChecked(enableJavaScript);
+        toggleDomStorage.setChecked(enableDomStorage);
+        /* toggleSaveFormData does nothing until database storage is implemented.
+        toggleSaveFormData.setChecked(enableSaveFormData);
+        */
+        toggleCookies.setChecked(enableCookies);
+
         return true;
     }
 
-    // @TargetApi(11) turns off the errors regarding copy and paste, which are removed from view in menu_webview.xml for lower version of Android.
     @Override
+    public boolean onPrepareOptionsMenu(Menu menu) {
+        // Enable Clear Cookies if there are any.
+        MenuItem clearCookies = menu.findItem(R.id.clearCookies);
+        clearCookies.setEnabled(cookieManager.hasCookies());
+
+        // Enable Back if canGoBack().
+        MenuItem back = menu.findItem(R.id.back);
+        back.setEnabled(mainWebView.canGoBack());
+
+        // Enable forward if canGoForward().
+        MenuItem forward = menu.findItem(R.id.forward);
+        forward.setEnabled(mainWebView.canGoForward());
+
+        // Run all the other default commands.
+        super.onPrepareOptionsMenu(menu);
+
+        // return true displays the menu.
+        return true;
+    }
+
+    @Override
+    // @TargetApi(11) turns off the errors regarding copy and paste, which are removed from view in menu_webview.xml for lower version of Android.
     @TargetApi(11)
+    // Remove Android Studio's warning about the dangers of using SetJavaScriptEnabled.
+    @SuppressLint("SetJavaScriptEnabled")
+    // removeAllCookies is deprecated, but it is required for API < 21.
+    @SuppressWarnings("deprecation")
     public boolean onOptionsItemSelected(MenuItem menuItem) {
         int menuItemId = menuItem.getItemId();
         ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
-        ActionBar actionBar = getSupportActionBar();
-        final WebView mainWebView = (WebView) findViewById(R.id.mainWebView);
 
         // Sets the commands that relate to the menu entries.
         switch (menuItemId) {
+            case R.id.toggleJavaScript:
+                if (enableJavaScript) {
+                    enableJavaScript = false;
+                    menuItem.setChecked(false);
+                    mainWebView.getSettings().setJavaScriptEnabled(false);
+                    mainWebView.reload();
+                } else {
+                    enableJavaScript = true;
+                    menuItem.setChecked(true);
+                    mainWebView.getSettings().setJavaScriptEnabled(true);
+                    mainWebView.reload();
+                }
+                return true;
+
+            case R.id.toggleDomStorage:
+                if (enableDomStorage) {
+                    enableDomStorage = false;
+                    menuItem.setChecked(false);
+                    mainWebView.getSettings().setDomStorageEnabled(false);
+                    mainWebView.reload();
+                } else {
+                    enableDomStorage = true;
+                    menuItem.setChecked(true);
+                    mainWebView.getSettings().setDomStorageEnabled(true);
+                    mainWebView.reload();
+                }
+                return true;
+
+            /* toggleSaveFormData does nothing until database storage is implemented.
+            case R.id.toggleSaveFormData:
+                if (enableSaveFormData) {
+                    enableSaveFormData = false;
+                    menuItem.setChecked(false);
+                    mainWebView.getSettings().setSaveFormData(false);
+                    mainWebView.reload();
+                } else {
+                    enableSaveFormData = true;
+                    menuItem.setChecked(true);
+                    mainWebView.getSettings().setSaveFormData(true);
+                    mainWebView.reload();
+                }
+                return true;
+            */
+
+            case R.id.toggleCookies:
+                if (enableCookies) {
+                    enableCookies = false;
+                    menuItem.setChecked(false);
+                    cookieManager.setAcceptCookie(false);
+                    mainWebView.reload();
+                } else {
+                    enableCookies = true;
+                    menuItem.setChecked(true);
+                    cookieManager.setAcceptCookie(true);
+                    mainWebView.reload();
+                }
+                return true;
+
+            case R.id.clearDomStorage:
+                WebStorage webStorage = WebStorage.getInstance();
+                webStorage.deleteAllData();
+                Toast.makeText(getApplicationContext(), "DOM storage deleted", Toast.LENGTH_SHORT).show();
+                return true;
+
+            case R.id.clearCookies:
+                if (Build.VERSION.SDK_INT < 21) {
+                    cookieManager.removeAllCookie();
+                } else {
+                    cookieManager.removeAllCookies(null);
+                }
+                Toast.makeText(getApplicationContext(), "Cookies deleted", Toast.LENGTH_SHORT).show();
+                return true;
+
             case R.id.home:
                 mainWebView.loadUrl(homepage);
-                break;
+                return true;
 
             case R.id.refresh:
-                mainWebView.loadUrl(formattedUrlString);
-                break;
+                mainWebView.reload();
+                return true;
 
             case R.id.back:
                 mainWebView.goBack();
-                break;
+                return true;
 
             case R.id.forward:
                 mainWebView.goForward();
-                break;
+                return true;
 
             case R.id.copyURL:
                 // Make sure that actionBar is not null.
@@ -279,7 +472,7 @@ public class Webview extends AppCompatActivity {
                     EditText urlTextBox = (EditText) actionBar.getCustomView().findViewById(R.id.urlTextBox);
                     clipboard.setPrimaryClip(ClipData.newPlainText("URL", urlTextBox.getText()));
                 }
-                break;
+                return true;
 
             case R.id.pasteURL:
                 // Make sure that actionBar is not null.
@@ -293,7 +486,7 @@ public class Webview extends AppCompatActivity {
                         e.printStackTrace();
                     }
                 }
-                break;
+                return true;
 
             case R.id.shareURL:
                 // Make sure that actionBar is not null.
@@ -305,7 +498,15 @@ public class Webview extends AppCompatActivity {
                     shareIntent.setType("text/plain");
                     startActivity(Intent.createChooser(shareIntent, "Share URL"));
                 }
-                break;
+                return true;
+
+            case R.id.addToHomescreen:
+                // Show the CreateHomeScreenShortcut AlertDialog and name this instance createShortcut.
+                AppCompatDialogFragment shortcutDialog = new CreateHomeScreenShortcut();
+                shortcutDialog.show(getSupportFragmentManager(), "createShortcut");
+
+                //Everything else will be handled by CreateHomeScreenShortcut and the associated listeners below.
+                return true;
 
             case R.id.downloads:
                 // Launch the system Download Manager.
@@ -315,9 +516,60 @@ public class Webview extends AppCompatActivity {
                 downloadManangerIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
 
                 startActivity(downloadManangerIntent);
+                return true;
+
+            case R.id.about:
+                // Show the AboutDialog AlertDialog and name this instance aboutDialog.
+                AppCompatDialogFragment aboutDialog = new AboutDialog();
+                aboutDialog.show(getSupportFragmentManager(), "aboutDialog");
+                return true;
+
+            case R.id.exit:
+                // Clear DOM storage.
+                WebStorage domStorage = WebStorage.getInstance();
+                domStorage.deleteAllData();
+
+                // Clear cookies.
+                if (Build.VERSION.SDK_INT < 21) {
+                    cookieManager.removeAllCookie();
+                } else {
+                    cookieManager.removeAllCookies(null);
+                }
+
+                // Destroy the internal state of the webview.
+                mainWebView.destroy();
+
+                // Close Privacy Browser.
+                finish();
+                return true;
+
+            default:
+                return super.onOptionsItemSelected(menuItem);
         }
+    }
 
-        return super.onOptionsItemSelected(menuItem);
+    @Override
+    public void onCreateHomeScreenShortcutCancel(DialogFragment dialog) {
+        // Do nothing because the user selected "Cancel".
+    }
+
+    @Override
+    public void onCreateHomeScreenShortcutCreate(DialogFragment dialog) {
+        // Get shortcutNameEditText from the alert dialog.
+        EditText shortcutNameEditText = (EditText) dialog.getDialog().findViewById(R.id.shortcutNameEditText);
+
+        // Create the bookmark shortcut based on formattedUrlString.
+        Intent bookmarkShortcut = new Intent();
+        bookmarkShortcut.setAction(Intent.ACTION_VIEW);
+        bookmarkShortcut.setData(Uri.parse(formattedUrlString));
+
+        // Place the bookmark shortcut on the home screen.
+        Intent placeBookmarkShortcut = new Intent();
+        placeBookmarkShortcut.putExtra("android.intent.extra.shortcut.INTENT", bookmarkShortcut);
+        placeBookmarkShortcut.putExtra("android.intent.extra.shortcut.NAME", shortcutNameEditText.getText().toString());
+        placeBookmarkShortcut.putExtra("android.intent.extra.shortcut.ICON", favoriteIcon);
+        placeBookmarkShortcut.setAction("com.android.launcher.action.INSTALL_SHORTCUT");
+        sendBroadcast(placeBookmarkShortcut);
     }
 
     // Override onBackPressed so that if mainWebView can go back it does when the system back button is pressed.
@@ -382,4 +634,4 @@ public class Webview extends AppCompatActivity {
             inputMethodManager.hideSoftInputFromWindow(mainWebView.getWindowToken(), 0);
         }
     }
-}
+}
\ No newline at end of file