View Javadoc
1   /*
2    * Copyright (C) 2003-2014 eXo Platform SAS.
3    *
4    * This is free software; you can redistribute it and/or modify it
5    * under the terms of the GNU Lesser General Public License as
6    * published by the Free Software Foundation; either version 3 of
7    * the License, or (at your option) any later version.
8    *
9    * This software is distributed in the hope that it will be useful,
10   * but WITHOUT ANY WARRANTY; without even the implied warranty of
11   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12   * Lesser General Public License for more details.
13   *
14   * You should have received a copy of the GNU Lesser General Public
15   * License along with this software; if not, write to the Free
16   * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
17   * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
18   */
19  package org.exoplatform.ui;
20  
21  import java.net.URI;
22  import java.net.URISyntaxException;
23  import java.util.ArrayList;
24  
25  import org.exoplatform.R;
26  import org.exoplatform.singleton.AccountSetting;
27  import org.exoplatform.utils.ExoConnectionUtils;
28  import org.exoplatform.utils.ExoConstants;
29  import org.exoplatform.utils.ExoDocumentUtils;
30  import org.exoplatform.widget.CompatibleFileOpenDialog;
31  import org.exoplatform.widget.ConnectionErrorDialog;
32  
33  import android.annotation.SuppressLint;
34  import android.app.Activity;
35  import android.os.AsyncTask;
36  import android.os.Bundle;
37  import android.util.Log;
38  import android.view.Menu;
39  import android.view.MenuItem;
40  import android.view.ViewGroup;
41  import android.webkit.CookieManager;
42  import android.webkit.CookieSyncManager;
43  import android.webkit.HttpAuthHandler;
44  import android.webkit.WebChromeClient;
45  import android.webkit.WebSettings;
46  import android.webkit.WebSettings.LayoutAlgorithm;
47  import android.webkit.WebSettings.PluginState;
48  import android.webkit.WebView;
49  import android.webkit.WebViewClient;
50  
51  public class WebViewActivity extends Activity {
52  
53    private static final String ACCOUNT_SETTING = "account_setting";
54  
55    private static final String LOG_TAG         = "eXo____WebViewActivity____";
56  
57    private WebViewLoadTask     mLoadTask;
58  
59    private WebView             _wvGadget;
60  
61    private String              _url;
62  
63    private String              _titlebar;
64  
65    private String              contentType;
66  
67    private MenuItem            loaderItem;
68  
69    private MenuItem            documentItem;
70  
71    public void onCreate(Bundle icicle) {
72  
73      super.onCreate(icicle);
74      setContentView(R.layout.webview);
75      setTitle("");
76  
77      /*
78       * restore the previous state
79       */
80      if (icicle != null) {
81        _url = icicle.getString(ExoConstants.WEB_VIEW_URL);
82        _titlebar = icicle.getString(ExoConstants.WEB_VIEW_TITLE);
83        contentType = icicle.getString(ExoConstants.WEB_VIEW_MIME_TYPE);
84        AccountSetting accountSetting = icicle.getParcelable(ACCOUNT_SETTING);
85        AccountSetting.getInstance().setInstance(accountSetting);
86        ArrayList<String> cookieList = AccountSetting.getInstance().cookiesList;
87        ExoConnectionUtils.setCookieStore(ExoConnectionUtils.cookiesStore, cookieList);
88      } else {
89        _url = getIntent().getStringExtra(ExoConstants.WEB_VIEW_URL);
90        _url = _url.replaceAll(" ", "%20");
91        _titlebar = getIntent().getStringExtra(ExoConstants.WEB_VIEW_TITLE);
92        contentType = getIntent().getStringExtra(ExoConstants.WEB_VIEW_MIME_TYPE);
93      }
94  
95      setupCookies(_url);
96      _wvGadget = (WebView) findViewById(R.id.WebView);
97      /*
98       * Ensure we can clear Webview cache and set no cache when loading data.
99       */
100     _wvGadget.clearCache(true);
101     _wvGadget.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);
102     _wvGadget.getSettings().setSupportZoom(true);
103     if (getIntent().getStringExtra(ExoConstants.WEB_VIEW_ALLOW_JS) != null) {
104       boolean allowJS = Boolean.parseBoolean(getIntent().getStringExtra(ExoConstants.WEB_VIEW_ALLOW_JS));
105       setJavascript(allowJS);
106     } else {
107       // Disable JS by default
108       setJavascript(false);
109     }
110 
111     // _wvGadget.getSettings().setPluginsEnabled(true);
112     _wvGadget.getSettings().setPluginState(PluginState.ON);
113     // TODO check the deprecated method
114     _wvGadget.getSettings().setLoadsImagesAutomatically(true);
115     // _wvGadget.addJavascriptInterface(this, "MainScreen");
116     // TODO check javascript interface annotation
117     _wvGadget.getSettings().setBuiltInZoomControls(true);
118     /*
119      * the method for controlling the layout of html. SINGLE_COLUMN moves all
120      * content into one column that is the width of the view.
121      */
122     if (contentType != null && contentType.startsWith(ExoDocumentUtils.IMAGE_TYPE)) {
123       _wvGadget.getSettings().setLayoutAlgorithm(LayoutAlgorithm.SINGLE_COLUMN);
124       _wvGadget.getSettings().setUseWideViewPort(false);
125     }
126     final Activity activity = this;
127 
128     _wvGadget.setWebChromeClient(new WebChromeClient() {
129       public void onProgressChanged(WebView view, int progress) {
130         setTitle(getResources().getString(R.string.LoadingData));
131         activity.setProgress(progress * 100);
132         setLoaderItemVisible(true);
133         if (progress == 100) {
134           setTitle(_titlebar);
135           setLoaderItemVisible(false);
136           if (contentType != null && documentItem != null)
137             documentItem.setVisible(true);
138         }
139       }
140     });
141     _wvGadget.setWebViewClient(new NewsWebviewClient());
142     onLoad();
143 
144   }
145 
146   @SuppressLint("SetJavaScriptEnabled")
147   public void setJavascript(boolean allowJS) {
148     _wvGadget.getSettings().setJavaScriptEnabled(allowJS);
149     _wvGadget.getSettings().setJavaScriptCanOpenWindowsAutomatically(allowJS);
150   }
151 
152   @Override
153   protected void onSaveInstanceState(Bundle outState) {
154     super.onSaveInstanceState(outState);
155     outState.putString(ExoConstants.WEB_VIEW_URL, _url);
156     outState.putString(ExoConstants.WEB_VIEW_TITLE, _titlebar);
157     outState.putString(ExoConstants.WEB_VIEW_MIME_TYPE, contentType);
158     outState.putParcelable(ACCOUNT_SETTING, AccountSetting.getInstance());
159   }
160 
161   @Override
162   public boolean onCreateOptionsMenu(Menu menu) {
163     getMenuInflater().inflate(R.menu.webview, menu);
164     loaderItem = menu.findItem(R.id.menu_webview_refresh);
165     documentItem = menu.findItem(R.id.menu_webview_open_document);
166     return super.onCreateOptionsMenu(menu);
167   }
168 
169   @Override
170   public boolean onOptionsItemSelected(MenuItem item) {
171     switch (item.getItemId()) {
172 
173     case R.id.menu_webview_open_document:
174       new CompatibleFileOpenDialog(this, contentType, _url, _titlebar).show();
175       break;
176 
177     default:
178       break;
179     }
180 
181     return true;
182   }
183 
184   private void setupCookies(String url) {
185     String domain = "";
186     try {
187       URI uri = new URI(url);
188       domain = uri.getHost();
189       if (uri.getPort() != -1) {
190         domain = domain + ":" + uri.getPort();
191       }
192 
193     } catch (URISyntaxException e) {
194       domain = url;
195       Log.w(LOG_TAG, "Setting cookie for invalid URL :" + url);
196     }
197 
198     CookieSyncManager.createInstance(this);
199     ArrayList<String> cookies = AccountSetting.getInstance().cookiesList;
200     if (cookies != null) {
201       for (String strCookie : cookies) {
202         CookieManager.getInstance().setCookie(url, strCookie);
203       }
204       CookieSyncManager.getInstance().sync();
205     }
206   }
207 
208   private void setLoaderItemVisible(boolean visible) {
209     if (loaderItem != null) {
210       loaderItem.setVisible(visible);
211     }
212   }
213 
214   @Override
215   protected void onPause() {
216     onCancelLoad();
217     super.onPause();
218   }
219 
220   @Override
221   public void finish() {
222     // Avoids leaking the ZoomButtonsController when leaving the activity
223     ViewGroup layout = (ViewGroup) getWindow().getDecorView();
224     layout.removeAllViews();
225     super.finish();
226   }
227 
228   @Override
229   public void onBackPressed() {
230     onCancelLoad();
231     if (_wvGadget != null && _wvGadget.canGoBack()) {
232       _wvGadget.goBack();
233     } else
234       finish();
235   }
236 
237   private void onLoad() {
238     if (ExoConnectionUtils.isNetworkAvailableExt(this)) {
239       if (mLoadTask == null || mLoadTask.getStatus() == WebViewLoadTask.Status.FINISHED) {
240         mLoadTask = (WebViewLoadTask) new WebViewLoadTask().execute();
241       }
242     } else {
243       new ConnectionErrorDialog(this).show();
244     }
245 
246   }
247 
248   private void onCancelLoad() {
249     if (mLoadTask != null && mLoadTask.getStatus() == WebViewLoadTask.Status.RUNNING) {
250       mLoadTask.cancel(true);
251       mLoadTask = null;
252     }
253   }
254 
255   private class WebViewLoadTask extends AsyncTask<Void, Void, Boolean> {
256     @Override
257     protected void onPreExecute() {
258       setTitle(getResources().getString(R.string.LoadingData));
259       setLoaderItemVisible(true);
260     }
261 
262     @Override
263     protected Boolean doInBackground(Void... params) {
264       setupCookies(_url);
265       return true;
266 
267     }
268 
269     @Override
270     protected void onPostExecute(Boolean result) {
271       if (result) {
272         _wvGadget.loadUrl(_url);
273       } else {
274         setLoaderItemVisible(false);
275         finish();
276       }
277 
278     }
279 
280     @Override
281     protected void onCancelled() {
282       setLoaderItemVisible(false);
283       super.onCancelled();
284     }
285 
286   }
287 
288   private class NewsWebviewClient extends WebViewClient {
289     @Override
290     public boolean shouldOverrideUrlLoading(WebView view, String url) {
291       view.loadUrl(url);
292       return true;
293     }
294 
295     @Override
296     public void onReceivedHttpAuthRequest(WebView view, HttpAuthHandler handler, String host, String realm) {
297       super.onReceivedHttpAuthRequest(view, handler, host, realm);
298       view.reload();
299     }
300   }
301 }