/*
* Catroid: An on-device visual programming system for Android devices
* Copyright (C) 2010-2016 The Catrobat Team
* (<http://developer.catrobat.org/credits>)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* An additional term exception under section 7 of the GNU Affero
* General Public License, version 3, is available at
* http://developer.catrobat.org/license_additional_term
*
* This program 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.catrobat.catroid.ui;
import android.annotation.SuppressLint;
import android.app.ActionBar;
import android.app.DownloadManager;
import android.app.ProgressDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Bitmap;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.KeyEvent;
import android.webkit.CookieManager;
import android.webkit.CookieSyncManager;
import android.webkit.DownloadListener;
import android.webkit.WebChromeClient;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import org.catrobat.catroid.R;
import org.catrobat.catroid.common.Constants;
import org.catrobat.catroid.utils.DownloadUtil;
import org.catrobat.catroid.utils.ToastUtil;
import org.catrobat.catroid.utils.Utils;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
@SuppressLint("SetJavaScriptEnabled")
public class WebViewActivity extends BaseActivity {
private static final String TAG = WebViewActivity.class.getSimpleName();
public static final String INTENT_PARAMETER_URL = "url";
public static final String ANDROID_APPLICATION_EXTENSION = ".apk";
public static final String MEDIA_FILE_PATH = "media_file_path";
public static final String CALLING_ACTIVITY = "calling_activity";
private static final String FILENAME_TAG = "fname=";
private WebView webView;
private boolean callMainMenu = false;
private String url;
private String callingActivity;
private ProgressDialog progressDialog;
private Intent resultIntent = new Intent();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_webview);
ActionBar actionBar = getActionBar();
actionBar.hide();
Intent intent = getIntent();
url = intent.getStringExtra(INTENT_PARAMETER_URL);
if (url == null) {
url = Constants.BASE_URL_HTTPS;
}
callingActivity = intent.getStringExtra(CALLING_ACTIVITY);
webView = (WebView) findViewById(R.id.webView);
webView.setWebChromeClient(new WebChromeClient() {
private ProgressDialog progressCircle;
@Override
public void onProgressChanged(WebView view, int progress) {
if (progressCircle == null) {
progressCircle = new ProgressDialog(view.getContext(), R.style.WebViewLoadingCircle);
progressCircle.setCancelable(true);
progressCircle.setProgressStyle(android.R.style.Widget_ProgressBar_Small);
try {
progressCircle.show();
} catch (Exception e) {
Log.e(TAG, "Exception while showing progress circle", e);
}
}
if (progress == 100) {
progressCircle.dismiss();
progressCircle = null;
}
}
});
webView.setWebViewClient(new MyWebViewClient());
webView.getSettings().setJavaScriptEnabled(true);
String language = String.valueOf(Constants.CURRENT_CATROBAT_LANGUAGE_VERSION);
String flavor = Constants.FLAVOR_DEFAULT;
String version = Utils.getVersionName(getApplicationContext());
String platform = Constants.PLATFORM_DEFAULT;
webView.getSettings().setUserAgentString("Catrobat/" + language + " " + flavor + "/"
+ version + " Platform/" + platform);
webView.loadUrl(url);
webView.setDownloadListener(new DownloadListener() {
@Override
public void onDownloadStart(String url, String userAgent, String contentDisposition, String mimetype,
long contentLength) {
Log.d(WebViewActivity.class.getSimpleName(), "contentDisposition: " + contentDisposition + " " + mimetype);
if (getExtensionFromContentDisposition(contentDisposition).contains(Constants.CATROBAT_EXTENSION)) {
DownloadUtil.getInstance().prepareDownloadAndStartIfPossible(WebViewActivity.this, url);
} else if (url.contains(Constants.LIBRARY_BASE_URL)) {
String name = getMediaNameFromUrl(url);
String mediaType = getMediaTypeFromContentDisposition(contentDisposition);
String fileName = name + getExtensionFromContentDisposition(contentDisposition);
String tempPath = null;
switch (mediaType) {
case Constants.MEDIA_TYPE_LOOK:
tempPath = Constants.TMP_LOOKS_PATH;
break;
case Constants.MEDIA_TYPE_SOUND:
tempPath = Constants.TMP_SOUNDS_PATH;
}
String filePath = Utils.buildPath(tempPath, fileName);
resultIntent.putExtra(MEDIA_FILE_PATH, filePath);
DownloadUtil.getInstance().prepareMediaDownloadAndStartIfPossible(WebViewActivity.this, url,
mediaType, name, filePath, callingActivity);
} else {
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
request.setTitle(getString(R.string.notification_download_title_pending) + " " + DownloadUtil.getInstance().getProjectNameFromUrl(url));
request.setDescription(getString(R.string.notification_download_pending));
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS,
DownloadUtil.getInstance().getProjectNameFromUrl(url) + ANDROID_APPLICATION_EXTENSION);
request.setMimeType(mimetype);
registerReceiver(onDownloadComplete, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
DownloadManager downloadManager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
downloadManager.enqueue(request);
}
}
});
}
BroadcastReceiver onDownloadComplete = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
long id = intent.getExtras().getLong(DownloadManager.EXTRA_DOWNLOAD_ID);
DownloadManager downloadManager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
intent = new Intent(Intent.ACTION_VIEW);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.setDataAndType(downloadManager.getUriForDownloadedFile(id),
downloadManager.getMimeTypeForDownloadedFile(id));
startActivity(intent);
}
};
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if ((keyCode == KeyEvent.KEYCODE_BACK) && webView.canGoBack()) {
callMainMenu = false;
webView.goBack();
return true;
}
return super.onKeyDown(keyCode, event);
}
private class MyWebViewClient extends WebViewClient {
@Override
public void onPageStarted(WebView view, String urlClient, Bitmap favicon) {
if (callMainMenu && urlClient.equals(Constants.BASE_URL_HTTPS)) {
Intent intent = new Intent(getBaseContext(), MainMenuActivity.class);
startActivity(intent);
}
}
@Override
public void onPageFinished(WebView view, String url) {
callMainMenu = true;
}
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if (url != null && url.startsWith(Constants.WHATSAPP_URI)) {
Uri uri = Uri.parse(url);
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(intent);
return true;
} else if (checkIfWebViewVisitExternalWebsite(url)) {
Uri uri = Uri.parse(url);
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);
return true;
}
return false;
}
@Override
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
ConnectivityManager cm = (ConnectivityManager) getBaseContext().getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
boolean isConnected = activeNetwork != null && activeNetwork.isConnectedOrConnecting();
int errorMessage;
if (!isConnected) {
errorMessage = R.string.error_internet_connection;
} else {
errorMessage = R.string.error_unknown_error;
}
ToastUtil.showError(getBaseContext(), errorMessage);
finish();
}
private boolean checkIfWebViewVisitExternalWebsite(String url) {
if (url.contains(Constants.BASE_URL_HTTPS) || url.contains(Constants.LIBRARY_BASE_URL)) {
return false;
}
return true;
}
}
public void createProgressDialog(String mediaName) {
progressDialog = new ProgressDialog(WebViewActivity.this);
progressDialog.setTitle(getString(R.string.notification_download_title_pending) + mediaName);
progressDialog.setMessage(getString(R.string.notification_download_pending));
progressDialog.setProgressStyle(progressDialog.STYLE_HORIZONTAL);
progressDialog.setProgress(0);
progressDialog.setMax(100);
progressDialog.setProgressNumberFormat(null);
progressDialog.show();
}
public void updateProgressDialog(long progress) {
if (progress == 100) {
progressDialog.setProgress(progressDialog.getMax());
setResult(RESULT_OK, resultIntent);
progressDialog.dismiss();
finish();
} else {
progressDialog.setProgress((int) progress);
}
}
public void dismissProgressDialog() {
progressDialog.dismiss();
}
public Intent getResultIntent() {
return resultIntent;
}
public void setResultIntent(Intent intent) {
resultIntent = intent;
}
private String getMediaNameFromUrl(String url) {
int mediaNameIndex = url.lastIndexOf(FILENAME_TAG) + FILENAME_TAG.length();
String mediaName = url.substring(mediaNameIndex);
try {
mediaName = URLDecoder.decode(mediaName, "UTF-8");
} catch (UnsupportedEncodingException e) {
Log.e(TAG, "Could not decode program name: " + mediaName, e);
return null;
}
return mediaName;
}
private String getMediaTypeFromContentDisposition(String contentDisposition) {
String mediaType = null;
for (String extension : Constants.IMAGE_EXTENSIONS) {
if (getExtensionFromContentDisposition(contentDisposition).compareTo(extension) == 0) {
mediaType = Constants.MEDIA_TYPE_LOOK;
}
}
for (String extention : Constants.SOUND_EXTENSIONS) {
if (getExtensionFromContentDisposition(contentDisposition).compareTo(extention) == 0) {
mediaType = Constants.MEDIA_TYPE_SOUND;
}
}
return mediaType;
}
private String getExtensionFromContentDisposition(String contentDisposition) {
int extensionIndex = contentDisposition.lastIndexOf('.');
String extension = contentDisposition.substring(extensionIndex);
extension = extension.substring(0, extension.length() - 1);
return extension;
}
//taken from http://stackoverflow.com/a/28998241/
@SuppressWarnings("deprecated")
@SuppressLint("NewApi")
public static void clearCookies(Context context) {
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP_MR1) {
CookieSyncManager cookieSyncMngr = CookieSyncManager.createInstance(context);
cookieSyncMngr.startSync();
CookieManager cookieManager = CookieManager.getInstance();
cookieManager.removeAllCookie();
cookieManager.removeSessionCookie();
cookieSyncMngr.stopSync();
cookieSyncMngr.sync();
} else {
CookieManager.getInstance().removeAllCookies(null);
CookieManager.getInstance().flush();
}
}
}