This document presents a comprehensive, technical deep-dive into the architecture, design, and implementation of the Smart Island Android application, utilizing metadata gathered and verified via the codebase-memory-mcp tools.
The application is structured around a reactive, unidirectional data flow (UDF) that links Android system events (notifications, battery state changes) to a persistent Jetpack Compose overlay window drawn over other applications.
graph TD
%% Events
AS[Android System] -->|System Notifications| NIL[SmartIslandNotificationListenerService]
AS -->|Power & Battery Broadcasts| SER[SystemEventReceiver]
%% Repositories and Data State
NIL -->|Parse, Filter & Forward| NR[SmartIslandNotificationRepository]
SER -->|Forward Charging / Battery State| NR
%% Settings
MA[MainActivity / Settings UI] -->|Update Sliders & Toggles| SR[SmartIslandSettingsRepository]
%% UI State & Rendering
SR -->|Flow Settings Updates| OS[SmartIslandOverlayService]
NR -->|Flow Active Notifications| VM[IslandViewModel]
VM -->|Compose State| OS
%% Overlay UI
OS -->|Draws overlay ComposeView| OV[IslandOverlayView]
OV -->|Gestures: Swipe Up, Swipe Down, Tap| VM
VM -->|Remove notification & cancel in system| NR
- Class: SmartIslandNotificationListenerService
-
Mechanism:
-
System Interception: Intercepts incoming notifications by extending Android's
NotificationListenerService. -
System Tray Suppression: If an incoming notification is classified as
IMPORTANCE_HIGH(Heads-Up notification), the service callscancelNotification(sbn.key)to suppress the default OS banner. Simultaneously, it posts the notification to the Smart Island overlay withautoExpand = trueto mimic a heads-up animation. -
Suppressed Keys Set: Maintains a local
suppressedKeysset to handle the cancellation sync so that notifications are not accidentally removed from the overlay state during the self-cancellation process. -
Classification Logic: Uses NotificationFilter to filter out system-level package alerts, empty notifications, and ongoing foreground tasks (unless they represent calls, music playback, or progress tasks). It categorizes notifications into one of the
IslandModecategories:-
Notification.CallStyle/Notification.CATEGORY_CALL$\rightarrow$ IslandMode.IncomingCall -
Notification.CATEGORY_TRANSPORTor notifications with media controllers/action labels$\rightarrow$ IslandMode.Music - Ongoing progress
$\rightarrow$ IslandMode.Music/IslandMode.Notification(context dependent) - Charging
$\rightarrow$ IslandMode.Battery - General notifications
$\rightarrow$ IslandMode.Notification
-
-
Media Session Binding: Inspects the notification extras for
Notification.EXTRA_MEDIA_SESSION. If found, it establishes aMediaControllerconnection to track play/pause states, position estimation, and metadata (title, artist, album artwork).
-
System Interception: Intercepts incoming notifications by extending Android's
- Class: SmartIslandOverlayService
- Mechanism:
- Application Overlay Window: Inflates and manages a custom
ComposeViewdrawn on the window manager using theTYPE_APPLICATION_OVERLAYflag. - Overlay View Tree Owners: Attaches custom Lifecycle, ViewModel, and SavedStateRegistry owners defined in OverlayViewTreeOwners directly to the window-hosted
ComposeView. This enables Jetpack Compose components and animations to run safely within the Service context without throwing standard runtime Activity missing context exceptions.
- Application Overlay Window: Inflates and manages a custom
The overlay window must not block touch events directed at underlying background apps (e.g. scrolling in Chrome, typing on a keyboard) when the island is collapsed.
-
Mechanism:
-
Frame vs. Region Insets:
-
Expanded State: The layout params are updated to allow touch capturing across the full frame (
TOUCHABLE_INSETS_FRAME) so that tapping outside the expanded island collapses the island. -
Collapsed State: Uses
TOUCHABLE_INSETS_REGION(integer value3). It registers a reflection-basedOnComputeInternalInsetsListeneron theViewTreeObserverof the window.
-
Expanded State: The layout params are updated to allow touch capturing across the full frame (
-
Region Boundary Calculation: When collapsed, it dynamically reads the bounding box of the small floating pill:
$$w = (\text{width} + 16) \times \text{density}$$ $$h = (\text{height} + 16) \times \text{density}$$ $$\text{left} = \frac{\text{screenWidth} - w}{2} + \text{xOffsetPx}$$ $$\text{right} = \text{left} + w$$ $$\text{top} = 0, \quad \text{bottom} = h$$ -
ROM Compatibility: Sets the computed bounding box into the
touchableRegion(ormTouchableRegionvia reflection to support customized OEM ROMs like MIUI/ColorOS) insideInternalInsetsInfo. Events outside this region pass directly to apps below.
-
Frame vs. Region Insets:
Swiping down on an expanded notification opens its origin app in a floating window (Freeform Multi-Window Mode).
-
Mechanism:
-
Freeform mode launching: Resolves the notification's
contentIntent. It specifies the windowing mode parameter5(WINDOWING_MODE_FREEFORM) within the launch options bundle. -
Launch Bounds Configuration: Configures a rectangular boundary centered on the screen:
$$\text{w} = \text{screenWidth} \times 0.90, \quad \text{h} = \text{screenHeight} \times 0.65$$ -
Android 14+ Background Privilege: Sets
MODE_BACKGROUND_ACTIVITY_START_ALLOWEDviaActivityOptions.setPendingIntentBackgroundActivityStartMode()to bypass Android 14's strict background activity launching restrictions.
-
Freeform mode launching: Resolves the notification's
State is persisted and exposed reactively using a repository pattern:
- SmartIslandSettingsRepository: Uses Android Jetpack
DataStore(Preferences) to persist user configurations (X/Y offsets, sizes, colors, enabled status). Exposes a reactiveFlow<SmartIslandSettings>. - SmartIslandNotificationRepository: Holds active notifications in a thread-safe
MutableStateFlow<List<IslandNotification>>. It receives posting/removal commands from services, synchronizing state with the UI.
The UI is built with custom-themed Jetpack Compose components. It implements high-fidelity spring animations and custom graphics rendering:
The IslandOverlayView implements custom touch interceptors:
- Tap Outside: Triggers the collapse animation of the expanded island.
-
Vertical Swiping: Uses
detectVerticalDragGestures:-
Swipe Up (Drag
$< -35\text{dp}$ ): Dismisses and clears the active notification. -
Swipe Down (Drag
$> 35\text{dp}$ ): Closes the island and launches the target application in freeform/floating window mode. -
Release Bounce: On release, any drag offset is animated back to
0fusing Compose's bouncy spring animation specs. -
Horizontal Swiping: Uses
detectHorizontalDragGesturesto swipe between pages of active stacked notifications, updating the active index and interpolating heights.
-
Swipe Up (Drag
-
Stack Indicator: When more than 1 notification is active, the collapsed island draws concentric black arcs (
drawArc) behind the left and right sides of the pill, visually indicating a stack of items.
The IslandCollapsedContent contains slots tailored to the active mode:
- Left Slot: Displays the app icon, caller contact picture, or media album art.
- Center Slot: A solid black circle that aligns with the physical front camera hole cutout.
- Right Slot: Contains dynamic indicators:
- Notification Mode: A customizable blue notification dot.
- Call Mode: An active timer (
CallTimer) that updates elapsed time inMM:SSformat. - Music Mode: A live 3-bar Audio Visualizer animation powered by infinite repeating scale animations.
- Battery Mode: A custom battery percent text displaying next to the charging glyph.
- Dotted Battery Ring: (DottedRing) A custom-drawn circular charging indicator. It uses infinite rotation and scale animations on the central bolt icon inside a custom dotted progress path.
- Wavy Seek Bar: (WavyMusicSeekBar) A custom music progress bar displaying a sine wave pattern that animates dynamically when music is playing.
- Click Bounce: (BounceClick) A custom modifier that runs callbacks after scaling the button down to
0.94fon click.
The SmartIslandHomeScreen is split into modular components:
- HeaderSection: Displays the app logo, tagline, and the master overlay switch.
- PermissionsSection: Displays alert cards showing whether system overlay drawing, notification listener access, and system overlay warnings are enabled.
- PositionsSection: Contains sliders to live-update the pill's width, height, corner radius, X-offset, and Y-offset.
- CustomizationsSection: Houses preset color palettes and a custom RGB color picker dialog for battery, notification dot, and music visualizer elements.
- AppShortcutsSection: Provides a quick-launch shortcut config card where users can select up to 8 apps to display inside the expanded island.
- GesturesSection: Implements an interactive tabbed guide with looping finger path animations and a try-it-yourself sandbox to preview swipes.
- SupportSection: Deep links to GitHub for starring, bug reports, and enhancements.
- AboutSection: Displays developer social links, version details, and privacy links.
The repository maintains an extensive test suite verifying logic boundaries:
| Test File | Target Area | What is Verified |
|---|---|---|
| SmartIslandNotificationRepositoryTest | Notification Repository | Event streams, posting, removing, timer resets, commands. |
| IslandModeMappingTest | Mode Classification | Correct mapping of categories (Call, Transport, Progress, Media buttons) to IslandMode. |
| NotificationPriorityTest | Interception Filters | Ignored packages/flags, ongoing notification filter constraints, edge-case actions. |
| SmartIslandSettingsTest | Settings Datastore | Preference serialization, updates, reset bounds, boundaries. |
| SystemEventReceiverTest | Battery & Power Receiver | Intent matching, charging state parsing, battery percentage change thresholds. |
| IslandOverlaySmokeTest | UI Compose Overlay | Smoke-testing Compose view creation, settings repository connection, overlay UI rendering. |
- Build tool: Gradle Kotlin DSL (
build.gradle.ktsfiles). - Dependencies: Jetpack Compose, Material 3, AndroidX Lifecycle, Coroutines, DataStore, and Dagger Hilt (for dependency injection).
- SDK Levels:
- Minimum SDK: 26 (Android 8.0)
- Target SDK: 36 (Android 16)
- Max Compile SDK compatibility checks up to Android 15 (SDK 35) are implemented in overlay touch listeners.