Skip to content

Commit

Permalink
Merge pull request #72 from amank22/rel_1.0.5
Browse files Browse the repository at this point in the history
Rel 1.0.5
  • Loading branch information
amank22 committed Feb 10, 2022
2 parents cd13e4d + 6c851cf commit d7341c2
Show file tree
Hide file tree
Showing 11 changed files with 196 additions and 16 deletions.
2 changes: 1 addition & 1 deletion api/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ plugins {

ext {
set("PUBLISH_GROUP_ID", Configuration.Api.artifactGroup)
if (Configuration.Api.isSnapshot || rootProject.ext["snapshot"] as Boolean) {
if (Configuration.Api.isSnapshot || rootProject.ext["snapshot"] as? Boolean == true) {
set("PUBLISH_VERSION", Configuration.Api.snapshotVersionName)
} else {
set("PUBLISH_VERSION", Configuration.Api.versionName)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import com.voxfinite.logvue.utils.Either

class AndroidLogStreamer {

fun stream(packageName: String): Flow<Either<LogCatErrors, ArrayList<LogCatMessage2>>> {
return AdbHelper.monitorLogs(packageName)
fun stream(packageName: String, filters: List<String>): Flow<Either<LogCatErrors, ArrayList<LogCatMessage2>>> {
return AdbHelper.monitorLogs(packageName, filters)
}

fun stop() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ object AdbHelper {
@OptIn(ExperimentalCoroutinesApi::class)
fun monitorLogs(
packageName: String,
filters: Array<String> = arrayOf("FA", "FA-SVC", "PDTLogging")
filters: List<String>
) = callbackFlow {
stopLogs = false
val currentSelectedDevice = Devices.currentDevice?.device
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import javax.annotation.concurrent.GuardedBy
class LogCatRunner(
val mDevice: IDevice,
pid: Long,
filters: Array<String> = arrayOf("FA", "FA-SVC")
filters: List<String>
) {

companion object {
Expand Down
1 change: 1 addition & 0 deletions app/src/main/kotlin/com/voxfinite/logvue/app/App.kt
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import com.voxfinite.logvue.ui.components.SideNavigation
import com.voxfinite.logvue.ui.components.dialogs.CrashDialog
import com.voxfinite.logvue.ui.components.dialogs.IntroDialog
import com.voxfinite.logvue.utils.*
import com.voxfinite.logvue.utils.plugins.PluginsHelper

@Composable
@Preview
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.voxfinite.logvue.processor

import com.voxfinite.logvue.api.models.LogLevel2
import com.voxfinite.logvue.adb.AndroidLogStreamer
import com.voxfinite.logvue.adb.LogCatErrors
import com.voxfinite.logvue.adb.LogErrorNoSession
Expand All @@ -17,6 +16,7 @@ import com.voxfinite.logvue.api.models.LogItem
import com.voxfinite.logvue.models.SessionInfo
import com.voxfinite.logvue.storage.Db
import com.voxfinite.logvue.utils.*
import com.voxfinite.logvue.utils.plugins.PluginsHelper

class MainProcessor {

Expand Down Expand Up @@ -82,8 +82,9 @@ class MainProcessor {
return@withContext
}
val packageName = sessionInfo.appPackage
val stream = streamer.stream(packageName)
val parsers = PluginsHelper.parsers()
val filters = parsers.map { it.filters() }.flatten()
val stream = streamer.stream(packageName, filters)
launch {
val successStream = stream.filter { it.isSuccess }.map { it.getOrNull() }
.filterNotNull()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.voxfinite.logvue.storage.serializer

import com.voxfinite.logvue.utils.plugins.PluginsHelper
import org.mapdb.CC
import org.mapdb.DataInput2
import org.mapdb.DataOutput2
Expand Down Expand Up @@ -53,16 +54,16 @@ class ObjectSerializer<T>(val classLoader: ClassLoader = Thread.currentThread().
/**
* Loader must be non-null;
*/
(`in`: InputStream?) : ObjectInputStream(`in`) {
(inputStream: InputStream?) : ObjectInputStream(inputStream) {
/**
* Use the given ClassLoader rather than using the system class
*/
@Throws(IOException::class, ClassNotFoundException::class)
override fun resolveClass(desc: ObjectStreamClass): Class<*> {
val name = desc.name
return try {
Class.forName(name, false, classLoader)
} catch (ex: ClassNotFoundException) {
PluginsHelper.tryResolveClass(name)
} catch (ignore: ClassNotFoundException) {
super.resolveClass(desc)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import androidx.compose.ui.unit.sp
import com.voxfinite.logvue.models.EventTypeNotSure
import com.voxfinite.logvue.api.models.LogItem
import com.voxfinite.logvue.ui.CustomTheme
import com.voxfinite.logvue.ui.components.common.CustomImage
import com.voxfinite.logvue.ui.components.common.NetworkImage
import com.voxfinite.logvue.ui.views.flow.FlowRow
import com.voxfinite.logvue.utils.Helpers
import com.voxfinite.logvue.utils.predictedEventType
Expand Down Expand Up @@ -94,8 +96,7 @@ fun LogTitle(logItem: LogItem, modifier: Modifier = Modifier) {
fun LogIcon(logItem: LogItem, modifier: Modifier = Modifier) {
Box(modifier.size(48.dp)) {
val sourceIcon = logItem.source.icon
val sourceIconPainter = painterResource(sourceIcon)
Image(sourceIconPainter, logItem.source.type, Modifier.size(36.dp))
CustomImage(sourceIcon, logItem.source.type, Modifier.size(36.dp))
val predictedEventType = logItem.predictedEventType()
if (predictedEventType != EventTypeNotSure) {
val typePainter = painterResource(predictedEventType.iconResource)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
package com.voxfinite.logvue.ui.components.common

import androidx.compose.foundation.Image
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.produceState
import androidx.compose.runtime.remember
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.graphics.painter.BitmapPainter
import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.loadImageBitmap
import androidx.compose.ui.res.loadSvgPainter
import androidx.compose.ui.res.loadXmlImageVector
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.Density
import com.voxfinite.logvue.utils.plugins.PluginsResourceLoader
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import org.xml.sax.InputSource
import java.io.File
import java.io.IOException
import java.net.URL

@OptIn(ExperimentalComposeUiApi::class)
@Composable
fun CustomImage(
url: String?,
contentDescription: String,
modifier: Modifier = Modifier,
contentScale: ContentScale = ContentScale.Fit
) {
if (url.isNullOrBlank()) return
if (url.startsWith("http://") || url.startsWith("https://")) {
NetworkImage(url, contentDescription, modifier, contentScale)
} else {
Image(painterResource(url, PluginsResourceLoader()), contentDescription, modifier, contentScale = contentScale)
}
}

@Composable
fun NetworkImage(
url: String?,
contentDescription: String,
modifier: Modifier = Modifier,
contentScale: ContentScale = ContentScale.Fit
) {
if (url.isNullOrBlank()) return
AsyncImage(
load = { loadImageBitmap(url) },
painterFor = { remember { BitmapPainter(it) } },
contentDescription, modifier, contentScale
)
}

@Composable
fun <T> AsyncImage(
load: suspend () -> T,
painterFor: @Composable (T) -> Painter,
contentDescription: String,
modifier: Modifier = Modifier,
contentScale: ContentScale = ContentScale.Fit,
) {
// should cache image
val image: T? by produceState<T?>(null) {
value = withContext(Dispatchers.IO) {
try {
load()
} catch (e: IOException) {
// instead of printing to console, you can also write this to log,
// or show some error placeholder
e.printStackTrace()
null
}
}
}

if (image != null) {
Image(
painter = painterFor(image!!),
contentDescription = contentDescription,
contentScale = contentScale,
modifier = modifier
)
}
}


/* Loading from file with java.io API */

fun loadImageBitmap(file: File): ImageBitmap =
file.inputStream().buffered().use(::loadImageBitmap)

fun loadSvgPainter(file: File, density: Density): Painter =
file.inputStream().buffered().use { loadSvgPainter(it, density) }

fun loadXmlImageVector(file: File, density: Density): ImageVector =
file.inputStream().buffered().use { loadXmlImageVector(InputSource(it), density) }

/* Loading from network with java.net API */

fun loadImageBitmap(url: String): ImageBitmap =
URL(url).openStream().buffered().use(::loadImageBitmap)

fun loadSvgPainter(url: String, density: Density): Painter =
URL(url).openStream().buffered().use { loadSvgPainter(it, density) }

fun loadXmlImageVector(url: String, density: Density): ImageVector =
URL(url).openStream().buffered().use { loadXmlImageVector(InputSource(it), density) }

/* Loading from network with Ktor client API (https://ktor.io/docs/client.html). */

/*
suspend fun loadImageBitmap(url: String): ImageBitmap =
urlStream(url).use(::loadImageBitmap)
suspend fun loadSvgPainter(url: String, density: Density): Painter =
urlStream(url).use { loadSvgPainter(it, density) }
suspend fun loadXmlImageVector(url: String, density: Density): ImageVector =
urlStream(url).use { loadXmlImageVector(InputSource(it), density) }
@OptIn(KtorExperimentalAPI::class)
private suspend fun urlStream(url: String) = HttpClient(CIO).use {
ByteArrayInputStream(it.get(url))
}
*/
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
package com.voxfinite.logvue.utils
package com.voxfinite.logvue.utils.plugins

import com.voxfinite.logvue.api.LogEventParser
import com.voxfinite.logvue.parsers.FirebaseParser
import com.voxfinite.logvue.storage.StorageHelper
import com.voxfinite.logvue.utils.AppLog
import org.pf4j.CompoundPluginDescriptorFinder
import org.pf4j.DefaultPluginManager
import org.pf4j.ManifestPluginDescriptorFinder
import org.pf4j.PropertiesPluginDescriptorFinder
import java.nio.file.Path
import kotlin.jvm.Throws

object PluginsHelper {

private class PluginManager(importPaths: List<Path>) : DefaultPluginManager(importPaths) {
internal class PluginManager(importPaths: List<Path>) : DefaultPluginManager(importPaths) {
override fun createPluginDescriptorFinder(): CompoundPluginDescriptorFinder {
return CompoundPluginDescriptorFinder() // Demo is using the Manifest file
// PropertiesPluginDescriptorFinder is commented out just to avoid error log
Expand All @@ -20,7 +22,7 @@ object PluginsHelper {
}
}

private val pluginManager by lazy {
internal val pluginManager by lazy {
val pluginsPath = StorageHelper.getPluginsPath()
AppLog.d(pluginsPath.toString())
PluginManager(listOf(pluginsPath))
Expand All @@ -33,7 +35,6 @@ object PluginsHelper {
fun load() {
// load the plugins
pluginManager.loadPlugins()

// enable a disabled plugin
// pluginManager.enablePlugin("welcome-plugin")

Expand All @@ -49,6 +50,21 @@ object PluginsHelper {
return allParsers
}

@Throws(ClassCastException::class)
fun tryResolveClass(className : String) : Class<*> {
pluginManager.resolvedPlugins.forEach {
val classLoader = it.pluginClassLoader
val resolvedClass: Class<*>?
try {
resolvedClass = Class.forName(className, false, classLoader)
return resolvedClass
} catch (ignore : ClassNotFoundException) {
// ignore
}
}
return Class.forName(className, false, Thread.currentThread().contextClassLoader)
}

private fun getDefaultParsers(): MutableList<LogEventParser> = arrayListOf(FirebaseParser())

fun stop() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.voxfinite.logvue.utils.plugins

import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.res.ResourceLoader
import java.io.InputStream

@OptIn(ExperimentalComposeUiApi::class)
class PluginsResourceLoader : ResourceLoader {
override fun load(resourcePath: String): InputStream {
PluginsHelper.pluginManager.resolvedPlugins.forEach {
val classLoader = it.pluginClassLoader
val resource = try {
classLoader.getResourceAsStream(resourcePath)
} catch (ignore : Exception) {
null
}
if (resource != null) {
return resource
}
}
// TODO(https://github.com/JetBrains/compose-jb/issues/618): probably we shouldn't use
// contextClassLoader here, as it is not defined in threads created by non-JVM
val contextClassLoader = Thread.currentThread().contextClassLoader!!
val resource = contextClassLoader.getResourceAsStream(resourcePath)
?: (::PluginsResourceLoader.javaClass).getResourceAsStream(resourcePath)
return requireNotNull(resource) { "Resource $resourcePath not found" }
}
}

0 comments on commit d7341c2

Please sign in to comment.