Skip to content

Commit

Permalink
fix: visualization no longers disappearing on process termination
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 Jan 19, 2025
1 parent b1b986a commit 718cffd
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import kotlinx.coroutines.launch
* @param clientFactory the client factory for backend communication
*/
@OptIn(ExperimentalCoroutinesApi::class)
@Suppress("TooGenericException") // all exceptions should be forwarded for display
class ConfigurationManager(clientFactory: ClientFactory) :
FlowReduxStateMachine<ConfigurationState, ConfigurationAction>(
initialState = ConfigurationState.Uninitialized(clientFactory = clientFactory)
Expand All @@ -59,9 +60,13 @@ class ConfigurationManager(clientFactory: ClientFactory) :
spec {
inState<ConfigurationState.Uninitialized> {
onEnter { state ->
val client = state.snapshot.clientFactory.connect()
val configuration = client.initializeConfiguration()
state.override { configuration.synchronizedOrErrorState(client) }
try {
val client = state.snapshot.clientFactory.connect()
val configuration = client.initializeConfiguration()
state.override { configuration.synchronizedOrErrorState(client) }
} catch (e: Exception) {

Check warning

Code scanning / detekt

The caught exception is too generic. Prefer catching specific exceptions to the case that is currently handled. Warning

The caught exception is too generic. Prefer catching specific exceptions to the case that is currently handled.
state.override { ConfigurationState.Error(e) }
}
}
}

Expand Down Expand Up @@ -142,6 +147,10 @@ class ConfigurationManager(clientFactory: ClientFactory) :
this.getConfiguration()
}

/**
* Try to get the configuration and if it fails, obtain set an empty configuration
* (configuration has possibly never been written)
*/
private suspend fun Client.initializeConfiguration() =
try {
Either.Right(this.getConfiguration())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import android.content.pm.PackageManager
import android.graphics.drawable.Drawable
import de.amosproj3.ziofa.api.processes.InstalledPackageInfo

/** Provides information about the installed packages on the system and caches this information. */
class PackageInformationProvider(private val packageManager: PackageManager) {

private val installedPackagesCache: Map<String, InstalledPackageInfo> by lazy {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import timber.log.Timber

/**
* Provides an updating list of running components, with components being apps (groups of processes)
* or standalone processes like native processes based on backend data and package info.
*/
class RunningComponentsProvider(
private val clientFactory: ClientFactory,
private val packageInformationProvider: PackageInformationProvider,
Expand All @@ -43,6 +47,10 @@ class RunningComponentsProvider(
}
}

/**
* Start polling the backend process list and update the [processesList] every
* [PROCESS_LIST_REFRESH_INTERVAL_MS] milliseconds.
*/
private suspend fun startPollingProcessList() {
while (true) {
delay(PROCESS_LIST_REFRESH_INTERVAL_MS)
Expand All @@ -51,11 +59,17 @@ class RunningComponentsProvider(
}
}

/** Group processes based on the [Process.cmd]. */
private fun Flow<List<Process>>.groupByProcessName() =
this.map { processList ->
processList.groupBy { process -> process.cmd.toReadableString() }
}

/**
* Separate grouped processes into apps and standalone processes like native processes. All
* processes where [Process.cmd] is a package name will be treated as
* [RunningComponent.Application].
*/
private fun Flow<Map<String, List<Process>>>.splitIntoAppsAndStandaloneProcesses() =
this.map { packageProcessMap ->
packageProcessMap.entries.map { (packageOrProcessName, processList) ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import de.amosproj3.ziofa.ui.visualization.utils.getActiveMetricsForPids
import de.amosproj3.ziofa.ui.visualization.utils.getPIDsOrNull
import de.amosproj3.ziofa.ui.visualization.utils.isValidSelection
import de.amosproj3.ziofa.ui.visualization.utils.toUIOptions
import kotlinx.collections.immutable.toImmutableList
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.MutableStateFlow
Expand Down Expand Up @@ -73,7 +74,15 @@ class VisualizationViewModel(
selectedComponent = activeComponent,
selectedMetric = activeMetric,
selectedTimeframe = activeTimeframe,
componentOptions = configuredComponents.toUIOptions(),
componentOptions =
configuredComponents
.toUIOptions()
.plus(
activeComponent
) // prevent the selected component from disappearing if process ends
.toSet() // convert to set to remove the duplicate if it is already in
// the list
.toImmutableList(),
metricOptions =
config.getActiveMetricsForPids(pids = activeComponent.getPIDsOrNull()),
timeframeOptions = if (activeMetric != null) DEFAULT_TIMEFRAME_OPTIONS else null,
Expand Down

0 comments on commit 718cffd

Please sign in to comment.