SWADroid/SWADroid/src/main/java/es/ugr/swad/swadroid/modules/Module.java
Amab 8fd41782ad Update to Android API 34 (Android 14) (#420)
## What changes were proposed in this pull request?
* Update to Android API 34 (Android 14)
* Remove Firebase Analytics

## How was this patch tested?

Manually.

Reviewed-on: #420
Co-authored-by: Amab <juanmi1982@gmail.com>
Co-committed-by: Amab <juanmi1982@gmail.com>
2023-06-10 14:44:45 +02:00

434 lines
13 KiB
Java

/*
* This file is part of SWADroid.
*
* Copyright (C) 2010 Juan Miguel Boyero Corral <juanmi1982@gmail.com>
*
* SWADroid 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.
*
* SWADroid 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 SWADroid. If not, see <http://www.gnu.org/licenses/>.
*/
package es.ugr.swad.swadroid.modules;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;
import org.ksoap2.SoapFault;
import org.ksoap2.transport.HttpResponseException;
import org.kxml2.kdom.Element;
import org.kxml2.kdom.Node;
import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException;
import java.lang.ref.WeakReference;
import java.net.SocketTimeoutException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.util.concurrent.TimeoutException;
import javax.net.ssl.SSLException;
import es.ugr.swad.swadroid.Constants;
import es.ugr.swad.swadroid.R;
import es.ugr.swad.swadroid.gui.MenuActivity;
import es.ugr.swad.swadroid.modules.login.Login;
import es.ugr.swad.swadroid.preferences.Preferences;
import es.ugr.swad.swadroid.utils.Utils;
import es.ugr.swad.swadroid.webservices.IWebserviceClient;
import es.ugr.swad.swadroid.webservices.SOAPClient;
/**
* Superclass for encapsulate common behavior of all modules.
*
* @author Juan Miguel Boyero Corral <juanmi1982@gmail.com>
*/
public abstract class Module extends MenuActivity {
/**
* Class Module's tag name for Logcat
*/
private static final String TAG = Constants.APP_TAG + " Module";
/**
* Async Task for background jobs
*/
private Connect connect;
/**
* Client for SWAD webservices
*/
private IWebserviceClient webserviceClient;
/**
* Webservice result.
*/
protected Object result;
/**
* Shows error messages.
*/
private AlertDialog errorDialog = null;
/**
* Connection available flag
*/
protected static boolean isConnected;
/**
* METHOD_NAME param for webservice request.
*/
private String METHOD_NAME = "";
/**
* Connects to SWAD and gets user data.
*
* @throws NoSuchAlgorithmException
* @throws IOException
* @throws XmlPullParserException
* @throws Exception
*/
protected abstract void requestService() throws Exception;
/**
* Launches action in a separate thread while shows a progress dialog in UI
* thread.
*/
protected abstract void connect();
/**
* Launches action after executing connect() method
*/
protected abstract void postConnect();
/**
* Error handler
*/
protected abstract void onError();
/**
* Run connection. Launch Login activity when required
*/
protected void runConnection() {
isConnected = Utils.connectionAvailable(this);
if (!isConnected) {
Toast.makeText(this, R.string.errorMsgNoConnection,
Toast.LENGTH_SHORT).show();
} else {
// If this is not the Login module, launch login check
if (!(this instanceof Login)) {
Intent loginActivity = new Intent(this, Login.class);
startActivityForResult(loginActivity,
Constants.LOGIN_REQUEST_CODE);
}
}
}
/*
* (non-Javadoc)
* @see android.app.Activity#onCreate()
*/
@Override
protected void onCreate(Bundle savedInstanceState) {
// Check if debug mode is enabled
try {
getPackageManager().getApplicationInfo(getPackageName(), 0);
isDebuggable = (ApplicationInfo.FLAG_DEBUGGABLE != 0);
} catch (NameNotFoundException e1) {
e1.printStackTrace();
}
// Initialize webservices client
webserviceClient = null;
super.onCreate(savedInstanceState);
// Recover the launched async task if the activity is re-created
connect = (Connect) getLastNonConfigurationInstance();
if (connect != null) {
connect.activity = new WeakReference<>(this);
}
}
/*
* @Override public Object onRetainNonConfigurationInstance() { return
* connect; }
*/
/*
* (non-Javadoc)
* @see android.app.Activity#onPause()
*/
@Override
protected void onPause() {
super.onPause();
if (errorDialog != null) {
errorDialog.dismiss();
}
}
/*
* (non-Javadoc)
* @see android.app.Activity#onResume()
*/
@Override
protected void onResume() {
super.onResume();
}
/*
* (non-Javadoc)
* @see android.app.Activity#onStart()
*/
@Override
protected void onStart() {
super.onStart();
}
/*
* (non-Javadoc)
* @see android.app.Activity#onActivityResult()
*/
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_OK) {
switch (requestCode) {
case Constants.LOGIN_REQUEST_CODE:
// Toast.makeText(getApplicationContext(),
// R.string.loginSuccessfulMsg,
// Toast.LENGTH_SHORT).show();
/*
* if(isDebuggable) Log.d(TAG,
* getString(R.string.loginSuccessfulMsg));
*/
if (!(this instanceof Login)) {
connect();
}
break;
}
} else {
setResult(RESULT_CANCELED);
finish();
}
}
/**
* Sets METHOD_NAME parameter.
*
* @param METHOD_NAME METHOD_NAME parameter.
*/
protected void setMETHOD_NAME(String METHOD_NAME) {
this.METHOD_NAME = METHOD_NAME;
}
/**
* Creates webservice request.
*/
protected void createRequest(String clientType) {
if (webserviceClient == null) {
if (clientType.equals(SOAPClient.CLIENT_TYPE)) {
webserviceClient = new SOAPClient();
}
webserviceClient.setMETHOD_NAME(METHOD_NAME);
}
webserviceClient.createRequest();
}
/**
* Adds a parameter to webservice request.
*
* @param param Parameter name.
* @param value Parameter value.
*/
protected void addParam(String param, Object value) {
webserviceClient.addParam(param, value);
}
/**
* Sends a SOAP request to the specified webservice in METHOD_NAME class
* constant of the webservice client.
*
* @param cl Class to be mapped
* @param simple Flag for select simple or complex response
* @throws Exception
*/
protected void sendRequest(Class<?> cl, boolean simple) throws Exception {
((SOAPClient) webserviceClient).sendRequest(cl, simple);
result = webserviceClient.getResult();
}
protected void startConnection() {
connect = new Connect(this);
connect.execute();
}
/**
* Shows progress dialog when connecting to SWAD
*/
class Connect extends AsyncTask<String, Void, Void> {
/**
* Activity that launched the task
*/
WeakReference<Module> activity;
/**
* Exception pointer
*/
Exception e;
/**
* Shows progress dialog and connects to SWAD in background
*
* @param activity Reference to Module activity
*/
public Connect(Module activity) {
super();
this.activity = new WeakReference<>(activity);
this.e = null;
}
/*
* (non-Javadoc)
* @see android.app.Activity#doInBackground()
*/
@Override
protected Void doInBackground(String... urls) {
if (isDebuggable) Log.d(TAG, "doInBackground()");
try {
// Sends webservice request
requestService();
/**
* If an exception occurs, capture, points exception pointer to
* it and shows error message according to exception type.
*/
} catch (Exception ex) {
e = ex;
}
return null;
}
/*
* (non-Javadoc)
* @see android.app.Activity#onPostExecute()
*/
@Override
protected void onPostExecute(Void unused) {
String errorMsg;
int httpStatusCode;
if (e != null) {
/**
* If an exception has occurred, shows error message according
* to exception type.
*/
if (e.getClass() == SoapFault.class) {
SoapFault es = (SoapFault) e;
switch (es.faultstring) {
case "Bad log in":
errorMsg = getString(R.string.errorBadLoginMsg);
break;
case "Bad web service key":
errorMsg = getString(R.string.errorBadLoginMsg);
// Force logout and reset password (this will show again
// the login screen)
Login.setLogged(false);
Preferences.setUserPassword("");
break;
case "Unknown application key":
errorMsg = getString(R.string.errorBadAppKeyMsg);
break;
default:
errorMsg = getSoapErrorMessage(es);
break;
}
} else if ((e.getClass() == TimeoutException.class) || (e.getClass() == SocketTimeoutException.class)) {
errorMsg = getString(R.string.errorTimeoutMsg);
} else if ((e.getClass() == CertificateException.class) || (e .getClass() == SSLException.class)) {
errorMsg = getString(R.string.errorServerCertificateMsg);
} else if (e.getClass() == HttpResponseException.class) {
httpStatusCode = ((HttpResponseException) e).getStatusCode();
Log.e(TAG, "httpStatusCode=" + httpStatusCode);
switch(httpStatusCode) {
case 500: errorMsg = getString(R.string.errorInternalServerMsg);
break;
case 503: errorMsg = getString(R.string.errorServiceUnavailableMsg);
break;
default: errorMsg = e.getMessage();
if ((errorMsg == null) || errorMsg.equals("")) {
errorMsg = getString(R.string.errorConnectionMsg);
}
}
} else if (e.getClass() == XmlPullParserException.class) {
errorMsg = getString(R.string.errorServerResponseMsg);
} else {
errorMsg = e.getMessage();
if ((errorMsg == null) || errorMsg.equals("")) {
errorMsg = getString(R.string.errorConnectionMsg);
}
}
// Request finalized with errors
error(errorMsg, e);
setResult(RESULT_CANCELED);
// Launch database rollback
if (dbHelper.isDbInTransaction()) {
dbHelper.endTransaction(false);
}
onError();
} else {
postConnect();
}
}
}
/**
* Method to retrieve the errorMessage from the given SoapFault.
* @param soapFault
* @return String representing the errorMessage found in the given SoapFault.
*/
private static String getSoapErrorMessage(SoapFault soapFault) {
String errorMessage;
try {
Node detailNode = soapFault.detail;
Element faultDetailElement = (Element)detailNode.getElement(0);
errorMessage = faultDetailElement.getText(0);
}
catch (Exception e) {
errorMessage = "Could not determine soap error.";
Log.e(TAG, errorMessage, e);
}
return errorMessage;
}
}