c75c35766ca9fcadd4882fc025c38a1330afa990
[PrivacyBrowser.git] / app / src / main / java / com / stoutner / privacybrowser / Webview.java
1 package com.stoutner.privacybrowser;
2
3 import android.app.Activity;
4 import android.content.Intent;
5 import android.net.Uri;
6 import android.os.Bundle;
7 import android.support.v4.widget.SwipeRefreshLayout;
8 import android.support.v7.app.AppCompatActivity;
9 import android.util.Patterns;
10 import android.view.KeyEvent;
11 import android.view.Menu;
12 import android.view.MenuItem;
13 import android.view.View;
14 import android.view.ViewTreeObserver;
15 import android.view.inputmethod.InputMethodManager;
16 import android.webkit.WebChromeClient;
17 import android.webkit.WebView;
18 import android.webkit.WebViewClient;
19 import android.widget.EditText;
20 import android.widget.ProgressBar;
21 import java.io.UnsupportedEncodingException;
22 import java.net.MalformedURLException;
23 import java.net.URL;
24 import java.net.URLEncoder;
25
26 public class Webview extends AppCompatActivity {
27
28     static String formattedUrlString;
29     static WebView mainWebView;
30     static ProgressBar progressBar;
31     static SwipeRefreshLayout swipeToRefresh;
32     static final String homepage = "https://www.duckduckgo.com";
33
34     @Override
35     protected void onCreate(Bundle savedInstanceState) {
36         super.onCreate(savedInstanceState);
37         setContentView(R.layout.activity_webview);
38
39         final EditText urlTextBox = (EditText) findViewById(R.id.urlTextBox);
40         swipeToRefresh = (SwipeRefreshLayout) findViewById(R.id.swipeRefreshLayoutContainer);
41         mainWebView = (WebView) findViewById(R.id.mainWebView);
42         progressBar = (ProgressBar) findViewById(R.id.progressBar);
43
44         // Implement swipe down to refresh.
45         swipeToRefresh.setColorSchemeColors(0xFF0097FF);
46         swipeToRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
47             @Override
48             public void onRefresh() {
49                 mainWebView.loadUrl(formattedUrlString);
50             }
51         });
52
53         // Only enable swipeToRefresh if is mainWebView is scrolled to the top.
54         mainWebView.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() {
55             @Override
56             public void onScrollChanged() {
57                 if (mainWebView.getScrollY() == 0) {
58                     swipeToRefresh.setEnabled(true);
59                 } else {
60                     swipeToRefresh.setEnabled(false);
61                 }
62             }
63         });
64
65         // setWebViewClient makes this WebView the default handler for URLs inside the app, so that links are not kicked out to other apps.
66         // Save the URL to formattedUrlString and update urlTextBox before loading mainWebView.
67         mainWebView.setWebViewClient(new WebViewClient() {
68             public boolean shouldOverrideUrlLoading(WebView view, String url) {
69                 formattedUrlString = url;
70                 urlTextBox.setText(formattedUrlString);
71                 mainWebView.loadUrl(formattedUrlString);
72                 return true;
73             }
74         });
75
76         // Update the progress bar when a page is loading.
77         mainWebView.setWebChromeClient(new WebChromeClient() {
78             public void onProgressChanged(WebView view, int progress) {
79                 progressBar.setProgress(progress);
80                 if (progress < 100) {
81                     progressBar.setVisibility(View.VISIBLE);
82                 } else {
83                     progressBar.setVisibility(View.GONE);
84                     // Stop the refreshing indicator if it is running.
85                     swipeToRefresh.setRefreshing(false);
86                 }
87             }
88         });
89
90         // Allow pinch to zoom.
91         mainWebView.getSettings().setBuiltInZoomControls(true);
92
93         // Hide zoom controls.
94         mainWebView.getSettings().setDisplayZoomControls(false);
95
96         // Enable JavaScript.
97         mainWebView.getSettings().setJavaScriptEnabled(true);
98
99         // Enable DOM Storage.
100         mainWebView.getSettings().setDomStorageEnabled(true);
101
102         // Get the intent information that started the app.
103         final Intent intent = getIntent();
104
105         if (intent.getData() != null) {
106             // Get the intent data and convert it to a string.
107             final Uri intentUriData = intent.getData();
108             Webview.formattedUrlString = intentUriData.toString();
109         }
110
111         // If formattedUrlString is null assign the homepage to it.
112         if (formattedUrlString == null) {
113             formattedUrlString = homepage;
114         }
115
116         // Place the formattedUrlString in the address bar and load the website.
117         urlTextBox.setText(formattedUrlString);
118         mainWebView.loadUrl(formattedUrlString);
119
120         // Set the "go" button on the keyboard to load the URL.
121         urlTextBox.setOnKeyListener(new View.OnKeyListener() {
122             public boolean onKey(View v, int keyCode, KeyEvent event) {
123                 // If the event is a key-down event on the "enter" button
124                 if ((event.getAction() == KeyEvent.ACTION_DOWN) &&
125                         (keyCode == KeyEvent.KEYCODE_ENTER)) {
126                     // Load the URL into the mainWebView and consume the event.
127                     try {
128                         loadUrlFromTextBox(mainWebView);
129                     } catch (UnsupportedEncodingException e) {
130                         e.printStackTrace();
131                     }
132                     return true;
133                 }
134                 // Do not consume the event.
135                 return false;
136             }
137         });
138
139     }
140
141     @Override
142     public boolean onCreateOptionsMenu(Menu menu) {
143         // Inflate the menu; this adds items to the action bar if it is present.
144         getMenuInflater().inflate(R.menu.menu_webview, menu);
145         return true;
146     }
147
148     @Override
149     public boolean onOptionsItemSelected(MenuItem menuItem) {
150         int menuItemId = menuItem.getItemId();
151         final WebView mainWebView = (WebView) findViewById(R.id.mainWebView);
152
153         // Sets the commands that relate to the menu entries.
154         switch (menuItemId) {
155             case R.id.home:
156                 mainWebView.loadUrl(homepage);
157                 break;
158             case R.id.back:
159                 mainWebView.goBack();
160                 break;
161             case R.id.forward:
162                 mainWebView.goForward();
163                 break;
164         }
165
166         return super.onOptionsItemSelected(menuItem);
167     }
168
169     // Override onBackPressed so that if mainWebView can go back it does when the system back button is pressed.
170     @Override
171     public void onBackPressed() {
172         if (mainWebView.canGoBack()) {
173             mainWebView.goBack();
174         } else {
175             super.onBackPressed();
176         }
177     }
178
179     public void loadUrlFromTextBox(View view) throws UnsupportedEncodingException {
180         // Get the text from urlTextInput and convert it to a string.
181         final EditText urlTextBox = (EditText) findViewById(R.id.urlTextBox);
182         final WebView mainWebView = (WebView) findViewById(R.id.mainWebView);
183         String unformattedUrlString = urlTextBox.getText().toString();
184         URL unformattedUrl = null;
185         Uri.Builder formattedUri = new Uri.Builder();
186         String scheme;
187
188         // Check to see if unformattedUrlString is a valid URL.  Otherwise, convert it into a Duck Duck Go search.
189         if (Patterns.WEB_URL.matcher(unformattedUrlString).matches()) {
190
191             // Add http:// at the beginning if it is missing.  Otherwise the app will segfault.
192             if (!unformattedUrlString.startsWith("http")) {
193                 unformattedUrlString = "http://" + unformattedUrlString;
194             }
195
196             // Convert unformattedUrlString to a URL, then to a URI, and then back to a string, which sanitizes the input and adds in any missing components.
197             try {
198                 unformattedUrl = new URL(unformattedUrlString);
199             } catch (MalformedURLException e) {
200                 e.printStackTrace();
201             }
202
203             if (unformattedUrl.getProtocol() != null) {
204                 scheme = unformattedUrl.getProtocol();
205             } else {
206                 scheme = "http";
207             }
208
209             final String authority = unformattedUrl.getAuthority();
210             final String path = unformattedUrl.getPath();
211             final String query = unformattedUrl.getQuery();
212             final String fragment = unformattedUrl.getRef();
213
214             formattedUri.scheme(scheme).authority(authority).path(path).query(query).fragment(fragment);
215             formattedUrlString = formattedUri.build().toString();
216
217         } else {
218             // Sanitize the search input.
219             final String encodedUrlString = URLEncoder.encode(unformattedUrlString, "UTF-8");
220             formattedUrlString = "https://duckduckgo.com/?q=" + encodedUrlString;
221         }
222
223         // Place formattedUrlString back in the address bar and load the website.
224         urlTextBox.setText(formattedUrlString);
225         mainWebView.loadUrl(formattedUrlString);
226
227         // Hides the keyboard so we can see the webpage.
228         InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE);
229         inputMethodManager.hideSoftInputFromWindow(mainWebView.getWindowToken(), 0);
230     }
231 }