Skip to content

Commit

Permalink
refactor: fix some code smells
Browse files Browse the repository at this point in the history
Signed-off-by: Luca Bretting <[email protected]>
  • Loading branch information
luca-dot-sh committed Dec 17, 2024
1 parent d5a267d commit 7b5abfe
Show file tree
Hide file tree
Showing 35 changed files with 217 additions and 206 deletions.
10 changes: 1 addition & 9 deletions .github/workflows/pull_request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -115,15 +115,7 @@ jobs:
--parallel \
--build-cache \
-Dorg.gradle.jvmargs=-Xmx4G
- name: Detekt
run: |
cd frontend
nix develop --command ./gradlew app:detekt \
--no-daemon \
--parallel \
--build-cache \
-Dorg.gradle.jvmargs=-Xmx4G
- name: Upload SARIF to GitHub using the upload-sarif action
- name: Upload Detekt results to GitHub
uses: github/codeql-action/upload-sarif@v2
if: success() || failure()
with:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,8 @@ package de.amosproj3.ziofa.api.events
import kotlinx.coroutines.flow.Flow

interface DataStreamProvider {
suspend fun counter(ebpfProgramName: String): Flow<UInt>

suspend fun vfsWriteEvents(pids: List<UInt>?): Flow<BackendEvent.VfsWriteEvent>
fun vfsWriteEvents(pids: List<UInt>?): Flow<BackendEvent.VfsWriteEvent>

suspend fun sendMessageEvents(pids: List<UInt>?): Flow<BackendEvent.SendMessageEvent>
fun sendMessageEvents(pids: List<UInt>?): Flow<BackendEvent.SendMessageEvent>
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import de.amosproj3.ziofa.client.JniReferencesConfig
import de.amosproj3.ziofa.client.SysSendmsgConfig
import de.amosproj3.ziofa.client.UprobeConfig
import de.amosproj3.ziofa.client.VfsWriteConfig
import de.amosproj3.ziofa.ui.shared.merge
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow
Expand Down Expand Up @@ -43,6 +44,7 @@ class ConfigurationManager(val clientFactory: ClientFactory) :
.map { it ?: ConfigurationUpdate.Unknown }

init {
@Suppress("TooGenericExceptionCaught") // we want to display all exceptions
coroutineScope.launch {
try {
client = clientFactory.connect()
Expand All @@ -63,48 +65,20 @@ class ConfigurationManager(val clientFactory: ClientFactory) :
_localConfiguration.update { prev ->
Timber.e("changeFeatureConfigurationForPIDs.prev $prev")
Timber.e(
"changeFeatureConfigurationForPIDs() $vfsWriteFeature, $sendMessageFeature, $uprobesFeature, $jniReferencesFeature"
"changeFeatureConfigurationForPIDs() " +
"vfs=$vfsWriteFeature, sendMsg=$sendMessageFeature, " +
"uprobes=$uprobesFeature, jni=$jniReferencesFeature"
)
// the configuration shall not be changed from the UI if there is none received from
// backend
if (prev != null && prev is ConfigurationUpdate.Valid) {
val previousConfiguration = prev.configuration
previousConfiguration
.copy(
vfsWrite =
vfsWriteFeature?.let { requestedChanges ->
previousConfiguration.vfsWrite.updatePIDs(
pidsToAdd =
if (enable) requestedChanges.entries.entries else setOf(),
pidsToRemove =
if (!enable) requestedChanges.entries.entries else setOf(),
)
} ?: previousConfiguration.vfsWrite,
sysSendmsg =
sendMessageFeature?.let { requestedChanges ->
previousConfiguration.sysSendmsg.updatePIDs(
pidsToAdd =
if (enable) requestedChanges.entries.entries else setOf(),
pidsToRemove =
if (!enable) requestedChanges.entries.entries else setOf(),
)
} ?: previousConfiguration.sysSendmsg,
uprobes =
uprobesFeature.let { requestedChanges ->
if (requestedChanges == null)
return@let previousConfiguration.uprobes
previousConfiguration.uprobes.updateUProbes(
pidsToAdd = if (enable) requestedChanges else listOf(),
pidsToRemove = if (!enable) requestedChanges else listOf(),
)
},
jniReferences =
jniReferencesFeature?.let { requestedChanges ->
previousConfiguration.jniReferences.updatePIDs(
pidsToAdd = if (enable) requestedChanges.pids else listOf(),
pidsToRemove = if (!enable) requestedChanges.pids else listOf(),
)
} ?: previousConfiguration.jniReferences,
vfsWrite = previousConfiguration.merge(vfsWriteFeature, enable),
sysSendmsg = previousConfiguration.merge(sendMessageFeature, enable),
uprobes = previousConfiguration.merge(uprobesFeature, enable),
jniReferences = previousConfiguration.merge(jniReferencesFeature, enable),
)
.also { Timber.i("new local configuration = $it") }
.let { ConfigurationUpdate.Valid(it) }
Expand All @@ -128,6 +102,7 @@ class ConfigurationManager(val clientFactory: ClientFactory) :
}
}

@Suppress("TooGenericExceptionCaught", "SwallowedException") // initialization mechanism
private suspend fun initializeConfigurations() {
val initializedConfiguration =
try {
Expand All @@ -139,6 +114,7 @@ class ConfigurationManager(val clientFactory: ClientFactory) :
}

// TODO this should be handled on the backend
@Suppress("TooGenericExceptionCaught") // we want to display all exceptions
private suspend fun getOrCreateInitialConfiguration(): ConfigurationUpdate {
return try {
// the config may not be initialized, we should try initializing it
Expand All @@ -162,6 +138,7 @@ class ConfigurationManager(val clientFactory: ClientFactory) :
} ?: Timber.e("unsubmittedConfiguration == null -> this should never happen")
}

@Suppress("TooGenericExceptionCaught") // we want to display all exceptions
private suspend fun getFromBackend(): ConfigurationUpdate {
return try {
(client?.getConfiguration()?.let { ConfigurationUpdate.Valid(it) }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.mapNotNull
import kotlinx.coroutines.flow.shareIn
import timber.log.Timber

class DataStreamManager(private val clientFactory: ClientFactory, coroutineScope: CoroutineScope) :
DataStreamProvider {
Expand All @@ -26,23 +25,7 @@ class DataStreamManager(private val clientFactory: ClientFactory, coroutineScope
flow { clientFactory.connect().initStream().collect { emit(it) } }
.shareIn(coroutineScope, SharingStarted.Lazily)

override suspend fun counter(ebpfProgramName: String): Flow<UInt> {
return clientFactory
.connect()
.also {
try {
it.load()
// default wifi interface on android, now configurable
it.attach("wlan0")
it.startCollecting()
} catch (e: Exception) {
Timber.e(e.stackTraceToString())
}
}
.serverCount()
}

override suspend fun vfsWriteEvents(pids: List<UInt>?): Flow<BackendEvent.VfsWriteEvent> =
override fun vfsWriteEvents(pids: List<UInt>?): Flow<BackendEvent.VfsWriteEvent> =
dataFlow
.mapNotNull { it as? Event.VfsWrite }
.filter { it.pid.isGlobalRequestedOrPidConfigured(pids) }
Expand All @@ -55,7 +38,7 @@ class DataStreamManager(private val clientFactory: ClientFactory, coroutineScope
)
}

override suspend fun sendMessageEvents(pids: List<UInt>?): Flow<BackendEvent.SendMessageEvent> =
override fun sendMessageEvents(pids: List<UInt>?): Flow<BackendEvent.SendMessageEvent> =
dataFlow
.mapNotNull { it as? Event.SysSendmsg }
.filter { it.pid.isGlobalRequestedOrPidConfigured(pids) }
Expand Down
52 changes: 23 additions & 29 deletions frontend/app/src/main/java/de/amosproj3/ziofa/ui/ZiofaApp.kt
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,19 @@ import de.amosproj3.ziofa.ui.visualization.VisualizationScreen
val GLOBAL_CONFIGURATION_ROUTE =
"${Routes.IndividualConfiguration.name}?displayName=${Uri.encode("all processes")}?pids=-1"

val PIDS_ARG =
navArgument("pids") {
type = NavType.StringType
nullable = true
}
val DISPLAY_NAME_ARG =
navArgument("displayName") {
type = NavType.StringType
nullable = true
}

/** Main application composable. All calls to [NavController] should happen here. */
@Suppress("ModifierMissing, LongMethod") // Top level composable
@Composable
fun ZIOFAApp() {
val navController = rememberNavController()
Expand All @@ -56,16 +68,16 @@ fun ZIOFAApp() {
}
screenWithDefaultAnimations(Routes.Reset.name) {
ResetScreen(
Modifier.padding(innerPadding),
afterResetConfirmed = { navController.popBackStack() },
modifier = Modifier.padding(innerPadding),
)
}
screenWithDefaultAnimations(Routes.Configuration.name) {
ConfigurationMenu(
Modifier.padding(innerPadding),
toProcesses = { navController.navigate(Routes.Processes.name) },
toGlobalConfiguration = { navController.navigate(GLOBAL_CONFIGURATION_ROUTE) },
toReset = { navController.navigate(Routes.Reset.name) },
modifier = Modifier.padding(innerPadding),
)
}
screenWithDefaultAnimations(Routes.Visualize.name) {
Expand All @@ -77,28 +89,17 @@ fun ZIOFAApp() {
screenWithDefaultAnimations(Routes.Processes.name) {
ProcessesScreen(
Modifier.padding(innerPadding),
onClickEdit = {
navController.navigate(it.toConfigurationScreenRouteForComponent())
onClickEdit = { component ->
navController.navigate(component.toConfigurationScreenRouteForComponent())
},
)
}
parameterizedScreen(
"${Routes.IndividualConfiguration.name}?displayName={displayName}?pids={pids}",
arguments =
listOf(
navArgument("displayName") {
type = NavType.StringType
nullable = true
},
navArgument("pids") {
type = NavType.StringType
nullable = true
},
),
arguments = listOf(DISPLAY_NAME_ARG, PIDS_ARG),
) {
ConfigurationScreen(
Modifier.padding(innerPadding),
onBack = { navController.popBackStack() },
pids = it.arguments?.getString("pids")?.deserializePIDs()?.validPIDsOrNull(),
onAddUprobeSelected = {
navController.navigate(it.arguments.copyToSymbolsRoute())
Expand All @@ -108,24 +109,17 @@ fun ZIOFAApp() {

parameterizedScreen(
"${Routes.Symbols.name}?displayName={displayName}?pids={pids}",
arguments =
listOf(
navArgument("displayName") {
type = NavType.StringType
nullable = true
},
navArgument("pids") {
type = NavType.StringType
nullable = true
},
),
arguments = listOf(DISPLAY_NAME_ARG, PIDS_ARG),
) {
SymbolsScreen(
modifier = Modifier.padding(innerPadding),
onSymbolsSubmitted = { navController.popBackStack() },
pids =
it.arguments?.getString("pids")?.deserializePIDs()?.validPIDsOrNull()
?: listOf(),
it.arguments
?.getString("pids")
?.deserializePIDs()
?.validPIDsOrNull()
.orEmpty(),
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,17 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp

const val PRODUCT_MISSION =
"ZIOFA (Zero Instrumentation Observability for Android) aims to implement observability use cases relevant to performance specified by our industry partner using eBPF. Examples include tracing long-running blocking calls, leaking JNI indirect references or signals like SIGKILL sent to processes, all without instrumenting the observed application itself.\n" +
"The eBPF programs are loaded and unloaded using a backend daemon running as root that will collect metrics and send them to a client. For displaying these metrics to the user, we are implementing an on-device UI that can display visualizations for these use cases and allow for configuration of the enabled use cases, but using a decoupled Client SDK so that future work may easily make the data accessible the external processing."
"ZIOFA (Zero Instrumentation Observability for Android) aims to implement observability use " +
"cases relevant to performance specified by our industry partner using eBPF. " +
"Examples include tracing long-running blocking calls, leaking JNI indirect" +
"references or signals like SIGKILL sent to processes, all without instrumenting" +
" the observed application itself.\n" +
"The eBPF programs are loaded and unloaded using a backend daemon running as root that " +
"will collect metrics and send them to a client. For displaying these metrics to " +
"the user, we are implementing an on-device UI that can display visualizations for" +
" these use cases and allow for configuration of the enabled use cases, but using a " +
"decoupled Client SDK so that future work may easily make the data accessible the " +
"external processing."

/**
* Screen containing information about the project. Might delete later if we need space for another
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ import org.koin.core.parameter.parametersOf
@Composable
fun ConfigurationScreen(
modifier: Modifier = Modifier,
onBack: () -> Unit = {},
onAddUprobeSelected: () -> Unit = {},
pids: List<UInt>? = listOf(),
) {
Expand All @@ -62,9 +61,7 @@ fun ConfigurationScreen(
SectionTitleRow("Uprobes")
EbpfUprobeFeatureOptions(
options =
state.options.mapNotNull {
if (it is BackendFeatureOptions.UprobeOption) it else null
},
state.options.mapNotNull { it as? BackendFeatureOptions.UprobeOption },
onOptionDeleted = { option ->
viewModel.optionChanged(option, active = false)
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@ import de.amosproj3.ziofa.ui.configuration.data.BackendFeatureOptions
fun EbpfIOFeatureOptions(
options: List<BackendFeatureOptions>,
onOptionChanged: (BackendFeatureOptions, Boolean) -> Unit,
modifier: Modifier = Modifier,
) {
LazyColumn(modifier = Modifier.padding(horizontal = 20.dp, vertical = 15.dp).fillMaxWidth()) {
LazyColumn(modifier = modifier.padding(horizontal = 20.dp, vertical = 15.dp).fillMaxWidth()) {
items(options) { option ->
Row(
modifier = Modifier.fillMaxWidth(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,9 @@ fun EbpfUprobeFeatureOptions(
options: List<BackendFeatureOptions.UprobeOption>,
onOptionDeleted: (BackendFeatureOptions.UprobeOption) -> Unit,
onAddUprobeSelected: () -> Unit,
modifier: Modifier = Modifier,
) {
LazyColumn(modifier = Modifier.padding(horizontal = 20.dp, vertical = 15.dp).fillMaxSize()) {
LazyColumn(modifier = modifier.padding(horizontal = 20.dp, vertical = 15.dp).fillMaxSize()) {
items(options) { option ->
Row(
modifier = Modifier.fillMaxWidth(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ import androidx.compose.ui.unit.TextUnitType
import androidx.compose.ui.unit.dp
import kotlin.system.exitProcess

const val TITLE_TEXT_SIZE = 25f

@Preview(device = Devices.AUTOMOTIVE_1024p)
@Composable
fun ErrorScreen(error: String = "No error message available") {
Expand All @@ -36,7 +38,7 @@ fun ErrorScreen(error: String = "No error message available") {
Text(
text = "Error while communicating with backend",
color = Color.Red,
fontSize = TextUnit(25f, TextUnitType.Sp),
fontSize = TextUnit(TITLE_TEXT_SIZE, TextUnitType.Sp),
)
Text(text = error)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp

@Composable
fun SectionTitleRow(title: String) {
Row(horizontalArrangement = Arrangement.Center, modifier = Modifier.padding(bottom = 10.dp)) {
fun SectionTitleRow(title: String, modifier: Modifier = Modifier) {
Row(horizontalArrangement = Arrangement.Center, modifier = modifier.padding(bottom = 10.dp)) {
Text(title, fontWeight = FontWeight.Bold)
}
HorizontalDivider(thickness = 3.dp)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,16 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import de.amosproj3.ziofa.ui.navigation.composables.MenuOptionData
import de.amosproj3.ziofa.ui.navigation.composables.MenuOptions
import de.amosproj3.ziofa.ui.navigation.data.Emoji
import de.amosproj3.ziofa.ui.navigation.data.MenuOptionData

@Composable
fun ConfigurationMenu(
modifier: Modifier = Modifier,
toProcesses: () -> Unit,
toGlobalConfiguration: () -> Unit,
toReset: () -> Unit,
modifier: Modifier = Modifier,
) {

Box(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Devices
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import de.amosproj3.ziofa.ui.navigation.composables.MenuOptionData
import de.amosproj3.ziofa.ui.navigation.composables.MenuOptions
import de.amosproj3.ziofa.ui.navigation.data.Emoji
import de.amosproj3.ziofa.ui.navigation.data.MenuOptionData

/** Static home screen for navigation */
@Composable
Expand Down
Loading

0 comments on commit 7b5abfe

Please sign in to comment.