diff --git a/app/src/main/java/com/itsaky/androidide/app/IDEApplication.kt b/app/src/main/java/com/itsaky/androidide/app/IDEApplication.kt
index 43a7ffd23..bc6ea567f 100755
--- a/app/src/main/java/com/itsaky/androidide/app/IDEApplication.kt
+++ b/app/src/main/java/com/itsaky/androidide/app/IDEApplication.kt
@@ -30,6 +30,7 @@ import androidx.work.NetworkType
import androidx.work.Operation
import androidx.work.PeriodicWorkRequestBuilder
import androidx.work.WorkManager
+import ch.qos.logback.classic.Logger
import com.blankj.utilcode.util.ThrowableUtils.getFullStackTrace
import com.google.android.material.color.DynamicColors
import com.itsaky.androidide.BuildConfig
@@ -43,6 +44,8 @@ import com.itsaky.androidide.events.EditorEventsIndex
import com.itsaky.androidide.events.LspApiEventsIndex
import com.itsaky.androidide.events.LspJavaEventsIndex
import com.itsaky.androidide.events.ProjectsApiEventsIndex
+import com.itsaky.androidide.logging.LogcatAppender
+import com.itsaky.androidide.logging.encoder.IDELogFormatEncoder
import com.itsaky.androidide.preferences.internal.DevOpsPreferences
import com.itsaky.androidide.preferences.internal.GeneralPreferences
import com.itsaky.androidide.preferences.internal.StatPreferences
@@ -50,7 +53,6 @@ import com.itsaky.androidide.resources.localization.LocaleProvider
import com.itsaky.androidide.stats.AndroidIDEStats
import com.itsaky.androidide.stats.StatUploadWorker
import com.itsaky.androidide.syntax.colorschemes.SchemeAndroidIDE
-import com.itsaky.androidide.tasks.executeAsync
import com.itsaky.androidide.treesitter.TreeSitter
import com.itsaky.androidide.ui.themes.IDETheme
import com.itsaky.androidide.ui.themes.IThemeManager
@@ -59,6 +61,9 @@ import com.itsaky.androidide.utils.VMUtils
import com.itsaky.androidide.utils.flashError
import com.termux.app.TermuxApplication
import io.github.rosemoe.sora.widget.schemes.EditorColorScheme
+import kotlinx.coroutines.DelicateCoroutinesApi
+import kotlinx.coroutines.GlobalScope
+import kotlinx.coroutines.launch
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
@@ -80,17 +85,17 @@ class IDEApplication : TermuxApplication() {
RecyclableObjectPool.DEBUG = BuildConfig.DEBUG
}
+ @OptIn(DelicateCoroutinesApi::class)
override fun onCreate() {
instance = this
uncaughtExceptionHandler = Thread.getDefaultUncaughtExceptionHandler()
-
Thread.setDefaultUncaughtExceptionHandler { thread, th -> handleCrash(thread, th) }
+
super.onCreate()
if (BuildConfig.DEBUG) {
StrictMode.setVmPolicy(
StrictMode.VmPolicy.Builder(StrictMode.getVmPolicy()).penaltyLog().detectAll().build())
-
if (DevOpsPreferences.dumpLogs) {
startLogcatReader()
}
@@ -110,7 +115,9 @@ class IDEApplication : TermuxApplication() {
EditorColorScheme.setDefault(SchemeAndroidIDE.newInstance(null))
- executeAsync { IDEColorSchemeProvider.init() }
+ GlobalScope.launch {
+ IDEColorSchemeProvider.init()
+ }
}
private fun handleCrash(thread: Thread, th: Throwable) {
diff --git a/app/src/main/java/com/itsaky/androidide/logging/IDELoggingConfigurator.kt b/app/src/main/java/com/itsaky/androidide/logging/IDELoggingConfigurator.kt
new file mode 100644
index 000000000..3a78e6b91
--- /dev/null
+++ b/app/src/main/java/com/itsaky/androidide/logging/IDELoggingConfigurator.kt
@@ -0,0 +1,50 @@
+/*
+ * This file is part of AndroidIDE.
+ *
+ * AndroidIDE 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.
+ *
+ * AndroidIDE 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 AndroidIDE. If not, see .
+ */
+
+package com.itsaky.androidide.logging
+
+import ch.qos.logback.classic.Logger
+import ch.qos.logback.classic.LoggerContext
+import ch.qos.logback.classic.spi.Configurator
+import ch.qos.logback.classic.spi.ConfiguratorRank
+import ch.qos.logback.core.spi.ContextAwareBase
+import com.google.auto.service.AutoService
+import com.itsaky.androidide.logging.encoder.IDELogFormatEncoder
+
+/**
+ * Default IDE logging configurator.
+ *
+ * @author Akash Yadav
+ */
+@ConfiguratorRank(ConfiguratorRank.CUSTOM_TOP_PRIORITY)
+@AutoService(Configurator::class)
+@Suppress("UNUSED")
+class IDELoggingConfigurator : ContextAwareBase(), Configurator {
+
+ override fun configure(context: LoggerContext): Configurator.ExecutionStatus {
+ addInfo("Setting up logging configuration")
+
+ val appender = LogcatAppender()
+ appender.encoder = IDELogFormatEncoder()
+ appender.start()
+
+ val rootLogger = context.getLogger(Logger.ROOT_LOGGER_NAME)
+ rootLogger.addAppender(appender)
+
+ return Configurator.ExecutionStatus.DO_NOT_INVOKE_NEXT_IF_ANY
+ }
+}
\ No newline at end of file
diff --git a/logger/src/main/java/com/itsaky/androidide/logging/LogcatAppender.java b/logger/src/main/java/com/itsaky/androidide/logging/LogcatAppender.java
index 267b04c7f..b37eb97ab 100644
--- a/logger/src/main/java/com/itsaky/androidide/logging/LogcatAppender.java
+++ b/logger/src/main/java/com/itsaky/androidide/logging/LogcatAppender.java
@@ -18,6 +18,7 @@ import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.UnsynchronizedAppenderBase;
+import com.itsaky.androidide.logging.encoder.IDELogFormatEncoder;
import com.itsaky.androidide.logging.utils.LogUtils;
/**
@@ -38,7 +39,7 @@ import com.itsaky.androidide.logging.utils.LogUtils;
*/
public class LogcatAppender extends UnsynchronizedAppenderBase {
- private PatternLayoutEncoder encoder = null;
+ private IDELogFormatEncoder encoder = null;
private boolean checkLoggable = false;
// AndroidIDE Changed: Appender is enabled only when running on Android.
@@ -132,7 +133,7 @@ public class LogcatAppender extends UnsynchronizedAppenderBase {
*
* @return the pattern-layout encoder
*/
- public PatternLayoutEncoder getEncoder() {
+ public IDELogFormatEncoder getEncoder() {
return this.encoder;
}
@@ -141,7 +142,7 @@ public class LogcatAppender extends UnsynchronizedAppenderBase {
*
* @param encoder the pattern-layout encoder
*/
- public void setEncoder(PatternLayoutEncoder encoder) {
+ public void setEncoder(IDELogFormatEncoder encoder) {
this.encoder = encoder;
}
diff --git a/logger/src/main/resources/logback.xml b/logger/src/main/resources/logback.xml
deleted file mode 100644
index df443c28b..000000000
--- a/logger/src/main/resources/logback.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-
-
-
-
- false
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/subprojects/tooling-api-impl/build.gradle.kts b/subprojects/tooling-api-impl/build.gradle.kts
index 3030cc18a..632957a78 100644
--- a/subprojects/tooling-api-impl/build.gradle.kts
+++ b/subprojects/tooling-api-impl/build.gradle.kts
@@ -21,6 +21,7 @@ import com.itsaky.androidide.build.config.BuildConfig
plugins {
id("com.github.johnrengelman.shadow") version "8.1.1"
id("java-library")
+ id("kotlin-kapt")
id("org.jetbrains.kotlin.jvm")
}
@@ -57,12 +58,15 @@ project.tasks.getByName("shadowJar") {
}
dependencies {
+ kapt(libs.google.auto.service)
+
api(projects.subprojects.toolingApi)
implementation(projects.buildInfo)
implementation(projects.shared)
implementation(libs.common.jkotlin)
+ implementation(libs.google.auto.service.annotations)
implementation(libs.xml.xercesImpl)
implementation(libs.xml.apis)
implementation(libs.tooling.gradleApi)
diff --git a/subprojects/tooling-api-impl/src/main/java/com/itsaky/androidide/tooling/impl/logging/ToolingLoggingConfigurator.kt b/subprojects/tooling-api-impl/src/main/java/com/itsaky/androidide/tooling/impl/logging/ToolingLoggingConfigurator.kt
new file mode 100644
index 000000000..d94881a53
--- /dev/null
+++ b/subprojects/tooling-api-impl/src/main/java/com/itsaky/androidide/tooling/impl/logging/ToolingLoggingConfigurator.kt
@@ -0,0 +1,55 @@
+/*
+ * This file is part of AndroidIDE.
+ *
+ * AndroidIDE 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.
+ *
+ * AndroidIDE 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 AndroidIDE. If not, see .
+ */
+
+package com.itsaky.androidide.tooling.impl.logging
+
+import ch.qos.logback.classic.Logger
+import ch.qos.logback.classic.LoggerContext
+import ch.qos.logback.classic.spi.Configurator
+import ch.qos.logback.classic.spi.ConfiguratorRank
+import ch.qos.logback.core.spi.ContextAwareBase
+import com.google.auto.service.AutoService
+import com.itsaky.androidide.logging.JvmStdErrAppender
+import com.itsaky.androidide.logging.encoder.IDELogFormatEncoder
+
+/**
+ * Default logging configurator for the Tooling API Runtime.
+ *
+ * @author Akash Yadav
+ */
+@ConfiguratorRank(ConfiguratorRank.CUSTOM_TOP_PRIORITY)
+@AutoService(Configurator::class)
+@Suppress("UNUSED")
+class ToolingLoggingConfigurator : ContextAwareBase(), Configurator {
+
+ override fun configure(context: LoggerContext): Configurator.ExecutionStatus {
+ addInfo("Setting up logging configuration for tooling API")
+
+ val stdErrAppender = JvmStdErrAppender()
+ stdErrAppender.encoder = IDELogFormatEncoder()
+ stdErrAppender.start()
+
+ val toolingApiAppender = ToolingApiAppender()
+ toolingApiAppender.start()
+
+ val rootLogger = context.getLogger(Logger.ROOT_LOGGER_NAME)
+ rootLogger.addAppender(stdErrAppender)
+ rootLogger.addAppender(toolingApiAppender)
+
+ return Configurator.ExecutionStatus.DO_NOT_INVOKE_NEXT_IF_ANY
+ }
+}
\ No newline at end of file
diff --git a/testing/common/build.gradle.kts b/testing/common/build.gradle.kts
index ddfa3ea6b..7dff8466d 100644
--- a/testing/common/build.gradle.kts
+++ b/testing/common/build.gradle.kts
@@ -18,9 +18,15 @@
@Suppress("JavaPluginLanguageLevel")
plugins {
id("java-library")
+ id("kotlin-kapt")
id("org.jetbrains.kotlin.jvm")
}
dependencies {
+ implementation(project(":subprojects:tooling-api-impl"))
+ kapt(libs.google.auto.service)
+ implementation(libs.google.auto.service.annotations)
+
api(libs.tests.junit)
+ api(projects.logger)
}
\ No newline at end of file
diff --git a/testing/common/src/main/java/com/itsaky/androidide/testing/common/logging/TestingLoggingConfgurator.kt b/testing/common/src/main/java/com/itsaky/androidide/testing/common/logging/TestingLoggingConfgurator.kt
new file mode 100644
index 000000000..ea4a0b946
--- /dev/null
+++ b/testing/common/src/main/java/com/itsaky/androidide/testing/common/logging/TestingLoggingConfgurator.kt
@@ -0,0 +1,46 @@
+/*
+ * This file is part of AndroidIDE.
+ *
+ * AndroidIDE 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.
+ *
+ * AndroidIDE 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 AndroidIDE. If not, see .
+ */
+
+package com.itsaky.androidide.testing.common.logging
+
+import ch.qos.logback.classic.Logger
+import ch.qos.logback.classic.LoggerContext
+import ch.qos.logback.classic.spi.Configurator
+import ch.qos.logback.classic.spi.ConfiguratorRank
+import ch.qos.logback.core.spi.ContextAwareBase
+import com.google.auto.service.AutoService
+import com.itsaky.androidide.logging.JvmStdErrAppender
+import com.itsaky.androidide.logging.encoder.IDELogFormatEncoder
+
+@ConfiguratorRank(ConfiguratorRank.CUSTOM_HIGH_PRIORITY)
+@AutoService(Configurator::class)
+@Suppress("UNUSED")
+class ToolingLoggingConfigurator : ContextAwareBase(), Configurator {
+
+ override fun configure(context: LoggerContext): Configurator.ExecutionStatus {
+ addInfo("Setting up logging configuration for test runtime")
+
+ val stdErrAppender = JvmStdErrAppender()
+ stdErrAppender.encoder = IDELogFormatEncoder()
+ stdErrAppender.start()
+
+ val rootLogger = context.getLogger(Logger.ROOT_LOGGER_NAME)
+ rootLogger.addAppender(stdErrAppender)
+
+ return Configurator.ExecutionStatus.DO_NOT_INVOKE_NEXT_IF_ANY
+ }
+}
\ No newline at end of file