App Allowlist & Detail Management
Relevant source files
The following files were used as context for generating this wiki page:
- app/src/main/kotlin/com/fathiraz/flowbell/presentation/screens/apps/AppDetailScreen.kt
- app/src/main/kotlin/com/fathiraz/flowbell/presentation/screens/apps/AppListRoute.kt
- app/src/main/kotlin/com/fathiraz/flowbell/data/repositories/AppPreferencesRepository.kt
- app/src/main/kotlin/com/fathiraz/flowbell/presentation/screens/apps/AppDetailViewModel.kt
- app/src/main/kotlin/com/fathiraz/flowbell/presentation/screens/analytics/AppListViewModel.kt
- app/src/main/kotlin/com/fathiraz/flowbell/domain/usecases/ManageAppPreferencesUseCase.kt
Introduction
App Allowlist & Detail Management is a core system within FlowBell that governs which applications are permitted to forward notifications to a configured webhook. This system provides a centralized interface for users to discover installed applications, toggle global forwarding permissions, and configure granular notification filters on a per-app basis. By utilizing an allowlist approach, FlowBell ensures that only trusted or specifically selected application alerts are processed, maintaining both security and relevance in the notification pipeline.
The system is structured around a multi-layered architecture involving Jetpack Compose for the UI, ViewModels for state management, and specialized repositories for persistence in a Room database. Users can navigate from a comprehensive list of all installed apps—filtered by notification permission status—to specific detail screens where they can manage keyword-based filters and forwarding toggles.
Sources: README.md, app/src/main/kotlin/com/fathiraz/flowbell/presentation/screens/apps/AppListRoute.kt:98-111
System Architecture
The management system follows Clean Architecture principles, separating the UI logic from the data persistence layer. It comprises the App List for broad management and the App Detail screen for specific configuration.
Data Flow for App Management
The following diagram illustrates how app preferences are loaded, modified, and persisted through the system layers.
A brief sentence explaining what the diagram shows: This diagram shows the unidirectional data flow from the User Interface down to the Room Database and back via StateFlow streams.
Sources: app/src/main/kotlin/com/fathiraz/flowbell/core/di/PresentationModule.kt:37-43, app/src/main/kotlin/com/fathiraz/flowbell/domain/usecases/ManageAppPreferencesUseCase.kt:12-20
App List Management
The App List serves as the primary gateway for the allowlist. It displays applications installed on the device that have notification access, as these are the only sources capable of triggering the forwarding service.
Components and Features
| Feature | Description |
|---|---|
| Notification Access Filter | Automatically restricts the list to apps with system-level notification permissions. |
| System Apps Toggle | Allows users to reveal or hide built-in system applications in the management list. |
| Search Functionality | Real-time filtering of the app list by application name or package name. |
| Forwarding Toggle | A high-level switch to enable or disable notification capturing for a specific app. |
Sources: app/src/main/kotlin/com/fathiraz/flowbell/presentation/screens/apps/AppListRoute.kt:100-145, app/src/main/kotlin/com/fathiraz/flowbell/presentation/screens/analytics/AppListViewModel.kt:66-88
App List Logic Flow
The sequence diagram details the process of refreshing the app list and toggling forwarding status for a specific application.
Sources: app/src/main/kotlin/com/fathiraz/flowbell/presentation/screens/analytics/AppListViewModel.kt:33-64
App Detail & Keyword Filtering
The App Detail screen provides granular control over the notification pipeline for a single application. This includes the implementation of a "Keyword Whitelist" system.
Keyword Filter System
If keyword filters are defined for an app, FlowBell will only forward notifications containing at least one of the specified keywords. If the list is empty, all notifications from that app are forwarded (provided global forwarding is enabled).
- Comma-Separated Input: Users provide keywords in a single text field, separated by commas.
- Persistence: Keywords are stored as a delimited string in the database and converted back to a list for logic processing.
- Case Insensitivity: Matching is performed without regard to case to ensure maximum reliability.
Sources: CHANGELOG.md:43-51, app/src/main/kotlin/com/fathiraz/flowbell/presentation/screens/apps/AppDetailScreen.kt:167-210
App Detail UI State Model
| Field | Type | Description |
|---|---|---|
packageName | String | Unique identifier for the application. |
isForwardingEnabled | Boolean | Global toggle for this app's notifications. |
filterWordsInput | String | Raw text input from the user for keywords. |
activeFilterWords | List | Sanitized list of keywords currently in effect. |
isSaving | Boolean | Loading state for database write operations. |
Sources: app/src/main/kotlin/com/fathiraz/flowbell/presentation/screens/apps/AppDetailViewModel.kt:14-23
Data Persistence & Repository
The AppPreferencesRepository manages the underlying data for the allowlist. It utilizes an "Upsert" pattern to ensure preferences exist for apps even before a user modifies them.
Key Implementation Details
// Example of the Upsert pattern used in the repository
// Source: app/src/main/kotlin/com/fathiraz/flowbell/data/repositories/AppPreferencesRepository.kt:30-49
suspend fun setForwardingEnabled(packageName: String, enabled: Boolean) {
val existingPreference = appPreferencesDao.getPreference(packageName)
if (existingPreference != null) {
appPreferencesDao.updateForwardingStatus(packageName, enabled, System.currentTimeMillis())
} else {
val newPreference = AppPreferences(
packageName = packageName,
isForwardingEnabled = enabled
)
appPreferencesDao.insertPreference(newPreference)
}
}
The repository handles:
- Status Retrieval: Checking if an app is currently in the allowlist.
- Keyword Management: Converting between
List<String>and the storedStringformat using.split(",")and.joinToString(","). - Initialization: Pre-populating the database with application metadata to speed up UI rendering.
Sources: app/src/main/kotlin/com/fathiraz/flowbell/data/repositories/AppPreferencesRepository.kt:29-55, app/src/main/kotlin/com/fathiraz/flowbell/data/repositories/AppPreferencesRepository.kt:105-125
Conclusion
The App Allowlist & Detail Management system provides the necessary controls to transform a broad stream of device notifications into a curated data source for webhooks. By combining a global allowlist with per-app keyword filtering, the system ensures that FlowBell remains an efficient and focused notification bridge. The architecture ensures that these preferences are persisted reliably across app restarts while providing a responsive, state-driven user experience.