Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Unverified Commit da4b5cf1 authored by Ricki Hirner's avatar Ricki Hirner
Browse files

DebugInfo: provide IntentBuilder that truncates large logs/local resource...

DebugInfo: provide IntentBuilder that truncates large logs/local resource dumps (should fix bitfireAT/davx5#69)
parent 248dd6fd
Loading
Loading
Loading
Loading
+37 −0
Original line number Original line Diff line number Diff line
/***************************************************************************************************
 * Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details.
 **************************************************************************************************/

package at.bitfire.davdroid.ui

import androidx.test.platform.app.InstrumentationRegistry
import org.junit.Assert.assertEquals
import org.junit.Test

class DebugInfoActivityTest {

    @Test
    fun testIntentBuilder_LargeLocalResource() {
        val a = 'A'.code.toByte()
        val intent = DebugInfoActivity.IntentBuilder(InstrumentationRegistry.getInstrumentation().context)
            .withLocalResource(String(ByteArray(1024*1024, { a })))
            .build()
        val expected = StringBuilder(DebugInfoActivity.IntentBuilder.MAX_ELEMENT_SIZE)
        expected.append(String(ByteArray(DebugInfoActivity.IntentBuilder.MAX_ELEMENT_SIZE - 3, { a })))
        expected.append("...")
        assertEquals(expected.toString(), intent.getStringExtra("localResource"))
    }

    @Test
    fun testIntentBuilder_LargeLogs() {
        val a = 'A'.code.toByte()
        val intent = DebugInfoActivity.IntentBuilder(InstrumentationRegistry.getInstrumentation().context)
            .withLogs(String(ByteArray(1024*1024, { a })))
            .build()
        val expected = StringBuilder(DebugInfoActivity.IntentBuilder.MAX_ELEMENT_SIZE)
        expected.append(String(ByteArray(DebugInfoActivity.IntentBuilder.MAX_ELEMENT_SIZE - 3, { a })))
        expected.append("...")
        assertEquals(expected.toString(), intent.getStringExtra("logs"))
    }

}
 No newline at end of file
+4 −4
Original line number Original line Diff line number Diff line
@@ -6,7 +6,6 @@ package at.bitfire.davdroid


import android.app.Application
import android.app.Application
import android.content.Context
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.net.Uri
import android.os.StrictMode
import android.os.StrictMode
import androidx.appcompat.content.res.AppCompatResources
import androidx.appcompat.content.res.AppCompatResources
@@ -87,9 +86,10 @@ class App: Application(), Thread.UncaughtExceptionHandler {
    override fun uncaughtException(t: Thread, e: Throwable) {
    override fun uncaughtException(t: Thread, e: Throwable) {
        Logger.log.log(Level.SEVERE, "Unhandled exception!", e)
        Logger.log.log(Level.SEVERE, "Unhandled exception!", e)


        val intent = Intent(this, DebugInfoActivity::class.java)
        val intent = DebugInfoActivity.IntentBuilder(this)
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
            .withCause(e)
        intent.putExtra(DebugInfoActivity.EXTRA_CAUSE, e)
            .newTask()
            .build()
        startActivity(intent)
        startActivity(intent)


        exitProcess(1)
        exitProcess(1)
+4 −4
Original line number Original line Diff line number Diff line
@@ -385,10 +385,10 @@ class DavService: IntentService("DavService") {
        } catch(e: Exception) {
        } catch(e: Exception) {
            Logger.log.log(Level.SEVERE, "Couldn't refresh collection list", e)
            Logger.log.log(Level.SEVERE, "Couldn't refresh collection list", e)


            val debugIntent = Intent(this, DebugInfoActivity::class.java)
            val debugIntent = DebugInfoActivity.IntentBuilder(this)
            debugIntent.putExtra(DebugInfoActivity.EXTRA_CAUSE, e)
                .withCause(e)
            debugIntent.putExtra(DebugInfoActivity.EXTRA_ACCOUNT, account)
                .withAccount(account)

                .build()
            val notify = NotificationUtils.newBuilder(this, NotificationUtils.CHANNEL_GENERAL)
            val notify = NotificationUtils.newBuilder(this, NotificationUtils.CHANNEL_GENERAL)
                    .setSmallIcon(R.drawable.ic_sync_problem_notify)
                    .setSmallIcon(R.drawable.ic_sync_problem_notify)
                    .setContentTitle(getString(R.string.dav_service_refresh_failed))
                    .setContentTitle(getString(R.string.dav_service_refresh_failed))
+4 −3
Original line number Original line Diff line number Diff line
@@ -94,9 +94,10 @@ object Logger : SharedPreferences.OnSharedPreferenceChangeListener {
                        .setContentText(context.getString(R.string.logging_notification_text, context.getString(R.string.app_name)))
                        .setContentText(context.getString(R.string.logging_notification_text, context.getString(R.string.app_name)))
                        .setOngoing(true)
                        .setOngoing(true)


                val shareIntent = Intent(Intent.ACTION_SEND, null, context, DebugInfoActivity::class.java)
                val shareIntent = DebugInfoActivity.IntentBuilder(context)
                shareIntent.putExtra(DebugInfoActivity.EXTRA_LOG_FILE, logFile.absolutePath)
                    .withLogFile(logFile)
                shareIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                    .newTask()
                    .share()
                val pendingShare = PendingIntent.getActivity(context, 0, shareIntent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE)
                val pendingShare = PendingIntent.getActivity(context, 0, shareIntent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE)
                builder.addAction(NotificationCompat.Action.Builder(
                builder.addAction(NotificationCompat.Action.Builder(
                        R.drawable.ic_share,
                        R.drawable.ic_share,
+16 −11
Original line number Original line Diff line number Diff line
@@ -44,6 +44,7 @@ import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext
import kotlinx.coroutines.withContext
import okhttp3.HttpUrl
import okhttp3.HttpUrl
import okhttp3.RequestBody
import okhttp3.RequestBody
import org.apache.commons.io.FileUtils
import org.apache.commons.lang3.exception.ContextedException
import org.apache.commons.lang3.exception.ContextedException
import org.dmfs.tasks.contract.TaskContract
import org.dmfs.tasks.contract.TaskContract
import java.io.IOException
import java.io.IOException
@@ -75,6 +76,7 @@ abstract class SyncManager<ResourceType: LocalResource<*>, out CollectionType: L
    }
    }


    companion object {
    companion object {
        const val DEBUG_INFO_MAX_RESOURCE_DUMP_SIZE = 100*FileUtils.ONE_KB.toInt()
        const val MAX_MULTIGET_RESOURCES = 10
        const val MAX_MULTIGET_RESOURCES = 10
    }
    }


@@ -763,17 +765,20 @@ abstract class SyncManager<ResourceType: LocalResource<*>, out CollectionType: L
    }
    }


    private fun buildDebugInfoIntent(e: Throwable, local: ResourceType?, remote: HttpUrl?) =
    private fun buildDebugInfoIntent(e: Throwable, local: ResourceType?, remote: HttpUrl?) =
            Intent(context, DebugInfoActivity::class.java).apply {
        DebugInfoActivity.IntentBuilder(context)
                putExtra(DebugInfoActivity.EXTRA_ACCOUNT, account)
            .withAccount(account)
                putExtra(DebugInfoActivity.EXTRA_AUTHORITY, authority)
            .withAuthority(authority)
                putExtra(DebugInfoActivity.EXTRA_CAUSE, e)
            .withCause(e)

            .withLocalResource(
                // pass current local/remote resource
                try {
                if (local != null)
                    local.toString()
                    putExtra(DebugInfoActivity.EXTRA_LOCAL_RESOURCE, local.toString())
                } catch (e: OutOfMemoryError) {
                if (remote != null)
                    // for instance because of a huge contact photo; maybe we're lucky and can fetch it
                    putExtra(DebugInfoActivity.EXTRA_REMOTE_RESOURCE, remote.toString())
                    null
                }
                }
            )
            .withRemoteResource(remote)
            .build()


    private fun buildRetryAction(): NotificationCompat.Action {
    private fun buildRetryAction(): NotificationCompat.Action {
        val retryIntent = Intent(context, DavService::class.java)
        val retryIntent = Intent(context, DavService::class.java)
Loading