Amab
8fd41782ad
## 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>
434 lines
13 KiB
Java
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;
|
|
}
|
|
}
|