Logger.kt 4.5 KB
Newer Older
Ricki Hirner's avatar
Ricki Hirner committed
1 2 3 4 5 6 7 8
/*
 * Copyright © 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
 */

9
package at.bitfire.davdroid.log
Ricki Hirner's avatar
Ricki Hirner committed
10

11
import android.app.PendingIntent
Ricki Hirner's avatar
Ricki Hirner committed
12
import android.content.Context
13
import android.content.Intent
14
import android.content.SharedPreferences
Ricki Hirner's avatar
Ricki Hirner committed
15
import android.os.Process
16
import android.preference.PreferenceManager
Ricki Hirner's avatar
Ricki Hirner committed
17 18 19
import android.support.v4.app.NotificationCompat
import android.support.v4.app.NotificationManagerCompat
import android.util.Log
20 21 22
import at.bitfire.davdroid.App
import at.bitfire.davdroid.Constants
import at.bitfire.davdroid.R
23
import at.bitfire.davdroid.ui.AppSettingsActivity
Ricki Hirner's avatar
Ricki Hirner committed
24 25 26 27 28 29 30 31
import org.apache.commons.lang3.time.DateFormatUtils
import java.io.File
import java.io.IOException
import java.util.logging.FileHandler
import java.util.logging.Level

object Logger {

32 33
    val LOG_TO_EXTERNAL_STORAGE = "log_to_external_storage"

Ricki Hirner's avatar
Ricki Hirner committed
34
    @JvmField
35 36 37 38 39 40 41 42 43
    val log = java.util.logging.Logger.getLogger("davdroid")!!


    lateinit var preferences: SharedPreferences

    fun initialize(context: Context) {
        preferences = PreferenceManager.getDefaultSharedPreferences(context)
        preferences.registerOnSharedPreferenceChangeListener { _, s ->
            if (s == LOG_TO_EXTERNAL_STORAGE)
Ricki Hirner's avatar
Ricki Hirner committed
44
                reinitialize(context.applicationContext)
Ricki Hirner's avatar
Ricki Hirner committed
45
        }
46

Ricki Hirner's avatar
Ricki Hirner committed
47
        reinitialize(context.applicationContext)
48 49
    }

Ricki Hirner's avatar
Ricki Hirner committed
50
    private fun reinitialize(context: Context) {
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
        val logToFile = preferences.getBoolean(LOG_TO_EXTERNAL_STORAGE, false)
        val logVerbose = logToFile || Log.isLoggable(log.name, Log.DEBUG)

        log.info("Verbose logging: $logVerbose; to file: $logToFile")

        // set logging level according to preferences
        val rootLogger = java.util.logging.Logger.getLogger("")
        rootLogger.level = if (logVerbose) Level.ALL else Level.INFO

        // remove all handlers and add our own logcat handler
        rootLogger.useParentHandlers = false
        rootLogger.handlers.forEach { rootLogger.removeHandler(it) }
        rootLogger.addHandler(LogcatHandler)

        val nm = NotificationManagerCompat.from(context)
        // log to external file according to preferences
        if (logToFile) {
            val builder = NotificationCompat.Builder(context)
69
            builder .setSmallIcon(R.drawable.ic_sd_storage_notification)
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
                    .setLargeIcon(App.getLauncherBitmap(context))
                    .setContentTitle(context.getString(R.string.logging_davdroid_file_logging))
                    .setLocalOnly(true)

            val dir = context.getExternalFilesDir(null)
            if (dir != null)
                try {
                    val fileName = File(dir, "davdroid-${Process.myPid()}-${DateFormatUtils.format(System.currentTimeMillis(), "yyyyMMdd-HHmmss")}.txt").toString()
                    log.info("Logging to $fileName")

                    val fileHandler = FileHandler(fileName)
                    fileHandler.formatter = PlainTextFormatter.DEFAULT
                    rootLogger.addHandler(fileHandler)

                    val prefIntent = Intent(context, AppSettingsActivity::class.java)
                    prefIntent.putExtra(AppSettingsActivity.EXTRA_SCROLL_TO, LOG_TO_EXTERNAL_STORAGE)

                    builder .setContentText(dir.path)
                            .setCategory(NotificationCompat.CATEGORY_STATUS)
                            .setPriority(NotificationCompat.PRIORITY_HIGH)
                            .setContentIntent(PendingIntent.getActivity(context, 0, prefIntent, PendingIntent.FLAG_UPDATE_CURRENT))
                            .setStyle(NotificationCompat.BigTextStyle()
                                    .bigText(context.getString(R.string.logging_to_external_storage, dir.path)))
                            .setOngoing(true)

                } catch(e: IOException) {
                    log.log(Level.SEVERE, "Couldn't create external log file", e)

                    builder .setContentText(context.getString(R.string.logging_couldnt_create_file, e.localizedMessage))
                            .setCategory(NotificationCompat.CATEGORY_ERROR)
                }
            else
                builder.setContentText(context.getString(R.string.logging_no_external_storage))

            nm.notify(Constants.NOTIFICATION_EXTERNAL_FILE_LOGGING, builder.build())
        } else
            nm.cancel(Constants.NOTIFICATION_EXTERNAL_FILE_LOGGING)
Ricki Hirner's avatar
Ricki Hirner committed
107 108 109
    }

}