2016-02-24 14:56:30 +00:00
|
|
|
|
/*
|
|
|
|
|
* Copyright © 2013 – 2016 Ricki Hirner (bitfire web engineering).
|
|
|
|
|
* All rights reserved. This program and the accompanying materials
|
|
|
|
|
* are made available under the terms of the GNU Public License v3.0
|
|
|
|
|
* which accompanies this distribution, and is available at
|
|
|
|
|
* http://www.gnu.org/licenses/gpl.html
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
package at.bitfire.davdroid;
|
|
|
|
|
|
2016-08-01 19:15:55 +00:00
|
|
|
|
import android.annotation.TargetApi;
|
2016-02-24 14:56:30 +00:00
|
|
|
|
import android.app.Application;
|
2016-03-24 18:05:58 +00:00
|
|
|
|
import android.content.BroadcastReceiver;
|
|
|
|
|
import android.content.Context;
|
2016-03-20 10:38:27 +00:00
|
|
|
|
import android.content.Intent;
|
2016-08-01 19:15:55 +00:00
|
|
|
|
import android.graphics.Bitmap;
|
2016-03-20 10:38:27 +00:00
|
|
|
|
import android.graphics.drawable.BitmapDrawable;
|
2016-08-01 19:15:55 +00:00
|
|
|
|
import android.graphics.drawable.Drawable;
|
|
|
|
|
import android.os.Build;
|
2016-10-04 20:41:52 +00:00
|
|
|
|
import android.os.Process;
|
2016-08-01 19:15:55 +00:00
|
|
|
|
import android.support.annotation.NonNull;
|
|
|
|
|
import android.support.annotation.Nullable;
|
2016-09-02 09:57:16 +00:00
|
|
|
|
import android.support.v4.app.NotificationManagerCompat;
|
2016-03-20 10:38:27 +00:00
|
|
|
|
import android.support.v7.app.NotificationCompat;
|
2016-02-24 22:08:19 +00:00
|
|
|
|
import android.util.Log;
|
|
|
|
|
|
|
|
|
|
import org.apache.commons.lang3.time.DateFormatUtils;
|
2016-02-24 14:56:30 +00:00
|
|
|
|
|
|
|
|
|
import java.io.File;
|
|
|
|
|
import java.io.IOException;
|
|
|
|
|
import java.util.logging.FileHandler;
|
|
|
|
|
import java.util.logging.Handler;
|
|
|
|
|
import java.util.logging.Level;
|
|
|
|
|
import java.util.logging.Logger;
|
|
|
|
|
|
|
|
|
|
import javax.net.ssl.HostnameVerifier;
|
|
|
|
|
|
2016-09-01 20:03:38 +00:00
|
|
|
|
import at.bitfire.cert4android.CustomCertManager;
|
2016-02-24 14:56:30 +00:00
|
|
|
|
import at.bitfire.davdroid.log.LogcatHandler;
|
2016-02-24 22:08:19 +00:00
|
|
|
|
import at.bitfire.davdroid.log.PlainTextFormatter;
|
2016-03-24 18:05:58 +00:00
|
|
|
|
import at.bitfire.davdroid.model.ServiceDB;
|
|
|
|
|
import at.bitfire.davdroid.model.Settings;
|
|
|
|
|
import lombok.Cleanup;
|
2016-02-24 14:56:30 +00:00
|
|
|
|
import lombok.Getter;
|
|
|
|
|
import okhttp3.internal.tls.OkHostnameVerifier;
|
|
|
|
|
|
2016-03-24 18:05:58 +00:00
|
|
|
|
public class App extends Application {
|
2016-06-23 21:47:40 +00:00
|
|
|
|
public static final String FLAVOR_GOOGLE_PLAY = "gplay";
|
|
|
|
|
|
2016-09-01 20:03:38 +00:00
|
|
|
|
public static final String
|
|
|
|
|
DISTRUST_SYSTEM_CERTIFICATES = "distrustSystemCerts",
|
2016-10-30 21:21:11 +00:00
|
|
|
|
LOG_TO_EXTERNAL_STORAGE = "logToExternalStorage",
|
|
|
|
|
OVERRIDE_PROXY = "overrideProxy",
|
|
|
|
|
OVERRIDE_PROXY_HOST = "overrideProxyHost",
|
|
|
|
|
OVERRIDE_PROXY_PORT = "overrideProxyPort";
|
|
|
|
|
|
|
|
|
|
public static final String OVERRIDE_PROXY_HOST_DEFAULT = "localhost";
|
|
|
|
|
public static final int OVERRIDE_PROXY_PORT_DEFAULT = 8118;
|
2016-02-24 14:56:30 +00:00
|
|
|
|
|
2016-03-18 16:24:46 +00:00
|
|
|
|
@Getter
|
2016-09-21 19:59:17 +00:00
|
|
|
|
private CustomCertManager certManager;
|
2016-03-18 16:24:46 +00:00
|
|
|
|
|
2016-02-24 14:56:30 +00:00
|
|
|
|
@Getter
|
|
|
|
|
private static SSLSocketFactoryCompat sslSocketFactoryCompat;
|
|
|
|
|
|
|
|
|
|
@Getter
|
|
|
|
|
private static HostnameVerifier hostnameVerifier;
|
|
|
|
|
|
|
|
|
|
public final static Logger log = Logger.getLogger("davdroid");
|
2016-05-25 18:50:02 +00:00
|
|
|
|
static {
|
2016-09-01 20:03:38 +00:00
|
|
|
|
at.bitfire.cert4android.Constants.log = Logger.getLogger("davdroid.cert4android");
|
2016-05-25 18:50:02 +00:00
|
|
|
|
}
|
2016-02-24 14:56:30 +00:00
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void onCreate() {
|
|
|
|
|
super.onCreate();
|
2016-09-01 20:03:38 +00:00
|
|
|
|
reinitCertManager();
|
|
|
|
|
reinitLogger();
|
|
|
|
|
}
|
2016-02-24 14:56:30 +00:00
|
|
|
|
|
2016-09-01 20:03:38 +00:00
|
|
|
|
public void reinitCertManager() {
|
|
|
|
|
if (BuildConfig.customCerts) {
|
|
|
|
|
if (certManager != null)
|
|
|
|
|
certManager.close();
|
2016-02-24 14:56:30 +00:00
|
|
|
|
|
2016-09-01 20:03:38 +00:00
|
|
|
|
@Cleanup ServiceDB.OpenHelper dbHelper = new ServiceDB.OpenHelper(this);
|
|
|
|
|
Settings settings = new Settings(dbHelper.getReadableDatabase());
|
|
|
|
|
|
|
|
|
|
certManager = new CustomCertManager(this, !settings.getBoolean(DISTRUST_SYSTEM_CERTIFICATES, false));
|
|
|
|
|
sslSocketFactoryCompat = new SSLSocketFactoryCompat(certManager);
|
|
|
|
|
hostnameVerifier = certManager.hostnameVerifier(OkHostnameVerifier.INSTANCE);
|
|
|
|
|
}
|
2016-02-24 14:56:30 +00:00
|
|
|
|
}
|
|
|
|
|
|
2016-03-24 18:05:58 +00:00
|
|
|
|
public void reinitLogger() {
|
|
|
|
|
@Cleanup ServiceDB.OpenHelper dbHelper = new ServiceDB.OpenHelper(this);
|
|
|
|
|
Settings settings = new Settings(dbHelper.getReadableDatabase());
|
|
|
|
|
|
|
|
|
|
boolean logToFile = settings.getBoolean(LOG_TO_EXTERNAL_STORAGE, false),
|
2016-02-24 22:08:19 +00:00
|
|
|
|
logVerbose = logToFile || Log.isLoggable(log.getName(), Log.DEBUG);
|
|
|
|
|
|
2016-10-17 15:45:59 +00:00
|
|
|
|
App.log.info("Verbose logging: " + logVerbose);
|
|
|
|
|
|
2016-02-24 14:56:30 +00:00
|
|
|
|
// set logging level according to preferences
|
2016-10-04 20:41:52 +00:00
|
|
|
|
final Logger rootLogger = Logger.getLogger("");
|
|
|
|
|
rootLogger.setLevel(logVerbose ? Level.ALL : Level.INFO);
|
2016-02-24 14:56:30 +00:00
|
|
|
|
|
2016-10-04 20:41:52 +00:00
|
|
|
|
// remove all handlers and add our own logcat handler
|
|
|
|
|
rootLogger.setUseParentHandlers(false);
|
|
|
|
|
for (Handler handler : rootLogger.getHandlers())
|
|
|
|
|
rootLogger.removeHandler(handler);
|
|
|
|
|
rootLogger.addHandler(LogcatHandler.INSTANCE);
|
2016-02-24 14:56:30 +00:00
|
|
|
|
|
2016-09-02 09:57:16 +00:00
|
|
|
|
NotificationManagerCompat nm = NotificationManagerCompat.from(this);
|
2016-02-24 14:56:30 +00:00
|
|
|
|
// log to external file according to preferences
|
2016-02-24 22:08:19 +00:00
|
|
|
|
if (logToFile) {
|
2016-03-20 10:38:27 +00:00
|
|
|
|
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
|
|
|
|
|
builder .setSmallIcon(R.drawable.ic_sd_storage_light)
|
2016-08-01 19:15:55 +00:00
|
|
|
|
.setLargeIcon(getLauncherBitmap(this))
|
2016-03-20 10:38:27 +00:00
|
|
|
|
.setContentTitle(getString(R.string.logging_davdroid_file_logging))
|
|
|
|
|
.setLocalOnly(true);
|
|
|
|
|
|
2016-02-24 14:56:30 +00:00
|
|
|
|
File dir = getExternalFilesDir(null);
|
|
|
|
|
if (dir != null)
|
|
|
|
|
try {
|
2016-10-04 20:41:52 +00:00
|
|
|
|
String fileName = new File(dir, "davdroid-" + Process.myPid() + "-" +
|
2016-03-24 18:05:58 +00:00
|
|
|
|
DateFormatUtils.format(System.currentTimeMillis(), "yyyyMMdd-HHmmss") + ".txt").toString();
|
|
|
|
|
log.info("Logging to " + fileName);
|
2016-02-24 14:56:30 +00:00
|
|
|
|
|
2016-03-24 18:05:58 +00:00
|
|
|
|
FileHandler fileHandler = new FileHandler(fileName);
|
2016-02-24 22:08:19 +00:00
|
|
|
|
fileHandler.setFormatter(PlainTextFormatter.DEFAULT);
|
2016-02-24 14:56:30 +00:00
|
|
|
|
log.addHandler(fileHandler);
|
2016-03-20 10:38:27 +00:00
|
|
|
|
builder .setContentText(dir.getPath())
|
|
|
|
|
.setSubText(getString(R.string.logging_to_external_storage_warning))
|
|
|
|
|
.setCategory(NotificationCompat.CATEGORY_STATUS)
|
|
|
|
|
.setPriority(NotificationCompat.PRIORITY_HIGH)
|
|
|
|
|
.setStyle(new NotificationCompat.BigTextStyle()
|
|
|
|
|
.bigText(getString(R.string.logging_to_external_storage, dir.getPath())))
|
|
|
|
|
.setOngoing(true);
|
|
|
|
|
|
2016-02-24 14:56:30 +00:00
|
|
|
|
} catch (IOException e) {
|
2016-03-20 10:38:27 +00:00
|
|
|
|
log.log(Level.SEVERE, "Couldn't create external log file", e);
|
|
|
|
|
|
|
|
|
|
builder .setContentText(getString(R.string.logging_couldnt_create_file, e.getLocalizedMessage()))
|
|
|
|
|
.setCategory(NotificationCompat.CATEGORY_ERROR);
|
2016-02-24 14:56:30 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
2016-03-20 10:38:27 +00:00
|
|
|
|
builder.setContentText(getString(R.string.logging_no_external_storage));
|
|
|
|
|
|
|
|
|
|
nm.notify(Constants.NOTIFICATION_EXTERNAL_FILE_LOGGING, builder.build());
|
|
|
|
|
} else
|
|
|
|
|
nm.cancel(Constants.NOTIFICATION_EXTERNAL_FILE_LOGGING);
|
2016-02-24 14:56:30 +00:00
|
|
|
|
}
|
|
|
|
|
|
2016-08-01 19:15:55 +00:00
|
|
|
|
@Nullable
|
|
|
|
|
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
|
|
|
|
public static Bitmap getLauncherBitmap(@NonNull Context context) {
|
|
|
|
|
Bitmap bitmapLogo = null;
|
|
|
|
|
Drawable drawableLogo = android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP ?
|
2016-09-01 20:40:46 +00:00
|
|
|
|
context.getDrawable(R.mipmap.ic_launcher) :
|
|
|
|
|
context.getResources().getDrawable(R.mipmap.ic_launcher);
|
2016-08-01 19:15:55 +00:00
|
|
|
|
if (drawableLogo instanceof BitmapDrawable)
|
|
|
|
|
bitmapLogo = ((BitmapDrawable)drawableLogo).getBitmap();
|
|
|
|
|
return bitmapLogo;
|
|
|
|
|
}
|
|
|
|
|
|
2016-03-24 18:05:58 +00:00
|
|
|
|
|
|
|
|
|
public static class ReinitLoggingReceiver extends BroadcastReceiver {
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void onReceive(Context context, Intent intent) {
|
|
|
|
|
log.info("Received broadcast: re-initializing logger");
|
|
|
|
|
|
|
|
|
|
App app = (App)context.getApplicationContext();
|
|
|
|
|
app.reinitLogger();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
2016-02-24 14:56:30 +00:00
|
|
|
|
}
|