PeachTileService.kt

2.9 KB · raw

1package com.peachpasswords.qs23import android.content.Context4import android.content.Intent5import android.graphics.drawable.Icon6import android.os.Build7import android.service.quicksettings.Tile8import android.service.quicksettings.TileService9import android.widget.Toast10import com.peachpasswords.MainActivity11import com.peachpasswords.R12import com.peachpasswords.vault.VaultRepository13import dagger.hilt.android.AndroidEntryPoint14import javax.inject.Inject1516/**17 * Quick Settings tile. Active when the vault is unlocked; tapping it copies the18 * most recently used entry's password to the clipboard. Locked → launches Peach19 * to the lock screen. The vault is a process singleton, so the tile sees the20 * live unlock state without its own session.21 */22@AndroidEntryPoint23class PeachTileService : TileService() {2425    @Inject lateinit var vault: VaultRepository2627    override fun onStartListening() {28        super.onStartListening()29        updateTile()30    }3132    override fun onClick() {33        super.onClick()34        if (vault.isUnlocked.value) {35            val recent = vault.entries.value36                .filter { !it.password.isNullOrEmpty() }37                .maxByOrNull { it.lastUsedAt ?: it.modifiedAt }38            if (recent?.password != null) {39                copyToClipboard(recent.title, recent.password!!)40                Toast.makeText(this, "Copied ${recent.title} password", Toast.LENGTH_SHORT).show()41            } else {42                Toast.makeText(this, "No entries to copy", Toast.LENGTH_SHORT).show()43            }44            updateTile()45        } else {46            launchApp()47        }48    }4950    private fun launchApp() {51        val intent = Intent(this, MainActivity::class.java).apply { flags = Intent.FLAG_ACTIVITY_NEW_TASK }52        if (Build.VERSION.SDK_INT >= 34) {53            startActivityAndCollapse(54                android.app.PendingIntent.getActivity(55                    this, 0, intent,56                    android.app.PendingIntent.FLAG_IMMUTABLE or android.app.PendingIntent.FLAG_UPDATE_CURRENT,57                ),58            )59        } else {60            @Suppress("DEPRECATION", "StartActivityAndCollapseDeprecated")61            startActivityAndCollapse(intent)62        }63    }6465    private fun copyToClipboard(label: String, value: String) {66        // Shared IS_SENSITIVE + 30s auto-clear path (MF-8).67        com.peachpasswords.shared.PeachClipboard.copy(this, label, value)68    }6970    private fun updateTile() {71        val tile = qsTile ?: return72        val unlocked = vault.isUnlocked.value73        tile.state = if (unlocked) Tile.STATE_ACTIVE else Tile.STATE_INACTIVE74        tile.label = "Peach"75        tile.contentDescription = if (unlocked) "Copy recent password" else "Unlock Peach"76        if (Build.VERSION.SDK_INT >= 29) {77            tile.subtitle = if (unlocked) "tap to copy" else "locked"78        }79        tile.icon = Icon.createWithResource(this, R.drawable.ic_peach_mark)80        tile.updateTile()81    }82}