Home / Specs / Clipboard Privacy
Settings v1.2.8

Clipboard Privacy

Password manager exclusion for clipboard history

Clipboard Privacy

Overview

CleverKeys includes privacy features for the clipboard history system, primarily automatic exclusion of clipboard entries from password managers. When enabled, CleverKeys detects when the foreground app is a password manager and skips storing clipboard content, preventing sensitive credentials from appearing in clipboard history.

Key Files

FileClass/FunctionPurpose
src/main/kotlin/tribixbite/cleverkeys/Config.ktPASSWORD_MANAGER_PACKAGESSet of excluded package names
src/main/kotlin/tribixbite/cleverkeys/ClipboardHistoryService.ktgetForegroundAppPackage()Detects current foreground app
src/main/kotlin/tribixbite/cleverkeys/ClipboardHistoryService.ktisPasswordManagerApp()Checks if package is excluded
src/main/kotlin/tribixbite/cleverkeys/ClipboardHistoryService.ktaddCurrentClip()Skips storage if excluded app
src/main/kotlin/tribixbite/cleverkeys/SettingsActivity.ktClipboard sectionUI toggle for feature

Architecture

Clipboard Change Event
       |
       v
+----------------------+
| ClipboardHistory     | -- System notifies of clipboard change
| Service              |
+----------------------+
       |
       v
+----------------------+
| getForegroundApp     | -- Detect which app copied
| Package()            |
+----------------------+
       |
       v
+----------------------+
| isPasswordManager    | -- Check against exclusion list
| App()                |
+----------------------+
       |
       v (if NOT excluded)
+----------------------+
| Store to clipboard   | -- Save to history database
| history              |
+----------------------+

Configuration

KeyTypeDefaultDescription
clipboard_exclude_password_managersBooleantrueSkip clipboard from password managers

Implementation Details

Supported Password Managers

Package names recognized (defined in Config.kt):

AppPackage Name
Bitwardencom.x8bit.bitwarden
1Passwordcom.onepassword.android, com.agilebits.onepassword
LastPasscom.lastpass.lpandroid
Dashlanecom.dashlane
KeePass2Androidkeepass2android.keepass2android
KeePassDXcom.kunzisoft.keepass.free, com.kunzisoft.keepass.pro
Enpassio.enpass.app
NordPasscom.nordpass.android.app.password.manager
RoboFormcom.siber.roboform
Keepercom.callpod.android_apps.keeper
Proton Passproton.android.pass
SafeInCloudcom.safeincloud
mSecurecom.msecure
Zoho Vaultcom.zoho.vault
Sticky Passwordcom.stickypassword.android

Foreground App Detection

Primary method uses UsageStatsManager (Android 5.1+):

private fun getForegroundAppPackage(): String? {
    val usageStatsManager = context.getSystemService(Context.USAGE_STATS_SERVICE)
        as UsageStatsManager
    val endTime = System.currentTimeMillis()
    val startTime = endTime - 1000 * 60  // Last minute

    val usageStats = usageStatsManager.queryUsageStats(
        UsageStatsManager.INTERVAL_DAILY, startTime, endTime
    )
    return usageStats.maxByOrNull { it.lastTimeUsed }?.packageName
}

Fallback uses ActivityManager (deprecated but still works):

private fun getForegroundAppPackageFallback(): String? {
    val activityManager = context.getSystemService(Context.ACTIVITY_SERVICE)
        as ActivityManager
    val runningTasks = activityManager.getRunningTasks(1)
    return runningTasks.firstOrNull()?.topActivity?.packageName
}

Exclusion Check

private fun isPasswordManagerApp(packageName: String?): Boolean {
    if (packageName == null) return false
    return PASSWORD_MANAGER_PACKAGES.contains(packageName)
}

private fun addCurrentClip() {
    if (config.clipboardExcludePasswordManagers) {
        val foregroundApp = getForegroundAppPackage()
        if (isPasswordManagerApp(foregroundApp)) {
            return  // Skip storage
        }
    }
    // Proceed with normal storage
    saveToHistory(clipboardManager.primaryClip)
}

Settings UI

SettingsSwitch(
    title = "Exclude Password Managers",
    description = "Don't store clipboard from Bitwarden, 1Password, LastPass, KeePass, etc.",
    checked = clipboardExcludePasswordManagers,
    onCheckedChange = {
        clipboardExcludePasswordManagers = it
        saveSetting("clipboard_exclude_password_managers", it)
    }
)

Security Considerations

Limitations