add custom wipe on inactivity timings

This commit is contained in:
lucky 2022-06-28 07:45:33 +03:00
parent 1abfef163a
commit 4e8737e50e
19 changed files with 95 additions and 61 deletions

View File

@ -22,7 +22,7 @@ message with authentication code. On trigger, using
locks a device and optionally runs wipe.
Also you can:
* wipe a device when it was not unlocked for N days
* wipe a device when it was not unlocked for N time
* wipe a device using a duress password (companion app: [Duress](https://github.com/x13a/Duress))
The app works in `Work Profile` too. Use [Shelter](https://github.com/PeterCxy/Shelter) to install

View File

@ -9,4 +9,4 @@
## Reporting a Vulnerability
Contact: mailto:44uaanjm0@relay.firefox.com
Contact: 44uaanjm0@relay.firefox.com

View File

@ -10,8 +10,8 @@ android {
applicationId "me.lucky.wasted"
minSdk 23
targetSdk 32
versionCode 25
versionName "1.4.0"
versionCode 26
versionName "1.4.1"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}

View File

@ -12,9 +12,11 @@ import android.view.View
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.core.widget.doAfterTextChanged
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.snackbar.Snackbar
import java.util.*
import java.util.regex.Pattern
import kotlin.concurrent.timerTask
import me.lucky.wasted.databinding.ActivityMainBinding
@ -22,6 +24,9 @@ import me.lucky.wasted.databinding.ActivityMainBinding
open class MainActivity : AppCompatActivity() {
companion object {
private const val CLIPBOARD_CLEAR_DELAY = 30_000L
private const val MODIFIER_DAYS = 'd'
private const val MODIFIER_HOURS = 'h'
private const val MODIFIER_MINUTES = 'm'
}
private lateinit var binding: ActivityMainBinding
@ -29,6 +34,8 @@ open class MainActivity : AppCompatActivity() {
private lateinit var admin: DeviceAdminManager
private val shortcut by lazy { ShortcutManager(this) }
private val job by lazy { WipeJobManager(this) }
private val wipeOnInactivityTimeRegex by lazy {
Pattern.compile("^[1-9]\\d*[$MODIFIER_DAYS$MODIFIER_HOURS$MODIFIER_MINUTES]$") }
private var clipboardManager: ClipboardManager? = null
private var clipboardClearTask: Timer? = null
@ -81,6 +88,7 @@ open class MainActivity : AppCompatActivity() {
wipeOnInactivitySwitch.isChecked = prefs.isWipeOnInactivity
toggle.isChecked = prefs.isEnabled
}
initWipeOnInactivityTime()
}
private fun hideEmbeddedSim() {
@ -96,22 +104,23 @@ open class MainActivity : AppCompatActivity() {
}
}
private fun initWipeOnInactivityTime() {
val count = prefs.wipeOnInactivityCount
val time = when {
count % (24 * 60) == 0 -> "${count / 24 / 60}$MODIFIER_DAYS"
count % 60 == 0 -> "${count / 60}$MODIFIER_HOURS"
else -> "$count$MODIFIER_MINUTES"
}
binding.wipeOnInactivityTime.editText?.setText(time)
}
private fun setup() {
binding.apply {
authenticationCode.setOnClickListener {
showTriggersSettings()
}
authenticationCode.setOnLongClickListener {
clipboardManager
?.setPrimaryClip(ClipData.newPlainText("", prefs.authenticationCode))
if (clipboardManager != null) {
scheduleClipboardClear()
Snackbar.make(
authenticationCode,
R.string.copied_popup,
Snackbar.LENGTH_SHORT,
).show()
}
copyAuthenticationCode()
true
}
wipeData.setOnCheckedChangeListener { _, isChecked ->
@ -125,9 +134,32 @@ open class MainActivity : AppCompatActivity() {
setWipeOnInactivityState(prefs.isEnabled && isChecked)
prefs.isWipeOnInactivity = isChecked
}
wipeOnInactivitySwitch.setOnLongClickListener {
showWipeOnInactivitySettings()
true
wipeOnInactivityTime.editText?.doAfterTextChanged {
if (wipeOnInactivityTimeRegex.matcher(it?.toString() ?: "").matches()) {
wipeOnInactivityTime.error = null
} else {
wipeOnInactivityTime.error = getString(R.string.wipe_on_inactivity_time_error)
}
}
wipeOnInactivityTime.setEndIconOnClickListener {
if (wipeOnInactivityTime.error != null) return@setEndIconOnClickListener
val time = wipeOnInactivityTime.editText?.text?.toString() ?: ""
if (time.length < 2) return@setEndIconOnClickListener
val modifier = time.last()
val i: Int
try {
i = time.dropLast(1).toInt()
} catch (exc: NumberFormatException) { return@setEndIconOnClickListener }
prefs.wipeOnInactivityCount = when (modifier) {
MODIFIER_DAYS -> i * 24 * 60
MODIFIER_HOURS -> i * 60
MODIFIER_MINUTES -> i
else -> return@setEndIconOnClickListener
}
if (prefs.isEnabled && prefs.isWipeOnInactivity) {
if (job.schedule() == JobScheduler.RESULT_FAILURE)
showWipeJobScheduleFailedPopup()
}
}
toggle.setOnCheckedChangeListener { _, isChecked ->
if (isChecked) requestAdmin() else setOff()
@ -135,6 +167,18 @@ open class MainActivity : AppCompatActivity() {
}
}
private fun copyAuthenticationCode() {
clipboardManager?.setPrimaryClip(ClipData.newPlainText("", prefs.authenticationCode))
if (clipboardManager != null) {
scheduleClipboardClear()
Snackbar.make(
binding.authenticationCode,
R.string.copied_popup,
Snackbar.LENGTH_SHORT,
).show()
}
}
private fun scheduleClipboardClear() {
clipboardClearTask?.cancel()
clipboardClearTask = Timer()
@ -174,27 +218,6 @@ open class MainActivity : AppCompatActivity() {
.show()
}
private fun showWipeOnInactivitySettings() {
val items = resources.getStringArray(R.array.wipe_on_inactivity_days)
var days = prefs.wipeOnInactivityCount / 24 / 60
var checked = items.indexOf(days.toString())
if (checked == -1) checked = items
.indexOf((Preferences.DEFAULT_WIPE_ON_INACTIVITY_COUNT / 24 / 60).toString())
MaterialAlertDialogBuilder(this)
.setTitle(R.string.wipe_on_inactivity_days)
.setSingleChoiceItems(items, checked) { _, which ->
days = items[which].toInt()
}
.setPositiveButton(android.R.string.ok) { _, _ ->
prefs.wipeOnInactivityCount = days * 24 * 60
if (prefs.isEnabled && prefs.isWipeOnInactivity) {
if (job.schedule() == JobScheduler.RESULT_FAILURE)
showWipeJobScheduleFailedPopup()
}
}
.show()
}
private fun updateCodeColorState() {
binding.authenticationCode.setBackgroundColor(getColor(
if (prefs.triggers != 0) R.color.code_on else R.color.code_off

View File

@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#000000"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM10,17l-5,-5 1.41,-1.41L10,14.17l7.59,-7.59L19,8l-9,9z"/>
</vector>

View File

@ -21,6 +21,7 @@
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginVertical="16dp"
android:isScrollContainer="false"
app:layout_constraintBottom_toTopOf="@+id/toggle"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
@ -91,6 +92,28 @@
android:layout_height="wrap_content"
android:text="@string/wipe_on_inactivity_description" />
<Space
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginVertical="8dp"/>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/wipeOnInactivityTime"
app:helperText="@string/wipe_on_inactivity_time_helper_text"
app:helperTextEnabled="true"
app:errorEnabled="true"
app:endIconMode="custom"
app:endIconDrawable="@drawable/ic_baseline_check_circle_24"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.textfield.TextInputEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/wipe_on_inactivity_time_hint" />
</com.google.android.material.textfield.TextInputLayout>
</LinearLayout>
</ScrollView>

View File

@ -15,7 +15,6 @@
<string name="shortcut_label">Panik</string>
<string name="wipe_on_inactivity_switch">Bei Inaktivität löschen</string>
<string name="wipe_on_inactivity_description">Den Speicher des Geräts löschen, wenn es für N Tage nicht entsperrt wurde.</string>
<string name="wipe_on_inactivity_days">Tage</string>
<string name="notification_channel_default_name">Standard</string>
<string name="wipe_job_description">Den Speicher bei Inaktivität löschen</string>
<string name="wipe_job_schedule_failed_popup">Fehler bei der Durchführung des Wipes</string>

View File

@ -15,7 +15,6 @@
<string name="shortcut_label">Pánico</string>
<string name="wipe_on_inactivity_switch">Borrar por inactividad</string>
<string name="wipe_on_inactivity_description">Limpia un dispositivo cuando no fue desbloqueado por N días.</string>
<string name="wipe_on_inactivity_days">Días</string>
<string name="notification_channel_default_name">Predeterminado</string>
<string name="wipe_job_description">Borrar un dispositivo por inactividad</string>
<string name="wipe_job_schedule_failed_popup">Error al programar un trabajo de borrado</string>

View File

@ -15,7 +15,6 @@
<string name="shortcut_label">Panico</string>
<string name="wipe_on_inactivity_switch">Cancella in caso di inattività</string>
<string name="wipe_on_inactivity_description">Cancella i dati quando il dispositivo non viene sbloccato per N giorni.</string>
<string name="wipe_on_inactivity_days">Giorni</string>
<string name="notification_channel_default_name">Predefinito</string>
<string name="wipe_job_description">Cancella i dati in caso di inattività</string>
<string name="wipe_job_schedule_failed_popup">Impossibile pianificare un processo di cancellazione</string>

View File

@ -15,7 +15,6 @@
<string name="shortcut_label">Тревога</string>
<string name="wipe_on_inactivity_switch">Стереть при неактивности</string>
<string name="wipe_on_inactivity_description">Стереть данные когда устройство не разблокируется N дней.</string>
<string name="wipe_on_inactivity_days">Дней</string>
<string name="notification_channel_default_name">По умолчанию</string>
<string name="wipe_job_description">Стереть данные при неактивности</string>
<string name="wipe_job_schedule_failed_popup">Не удалось запланировать сервис стирания данных</string>

View File

@ -15,7 +15,6 @@
<string name="shortcut_label">Panik</string>
<string name="wipe_on_inactivity_switch">Kullanılmadığında sil</string>
<string name="wipe_on_inactivity_description">N gün boyunca kilidi açılmamış bir cihazı silin.</string>
<string name="wipe_on_inactivity_days">Gün</string>
<string name="notification_channel_default_name">Varsayılan</string>
<string name="wipe_job_description">Cihaz kullanılmadığında siler</string>
<string name="wipe_job_schedule_failed_popup">Silme işi zamanlanamadı</string>

View File

@ -15,7 +15,6 @@
<string name="shortcut_label">Тривога</string>
<string name="wipe_on_inactivity_switch">Wipe on inactivity</string>
<string name="wipe_on_inactivity_description">Видалення пристрою, коли його не було розблоковано протягом N днів.</string>
<string name="wipe_on_inactivity_days">Днів</string>
<string name="notification_channel_default_name">За замовчуванням</string>
<string name="wipe_job_description">Wipe a device on inactivity</string>
<string name="wipe_job_schedule_failed_popup">Failed to schedule a wipe job</string>

View File

@ -15,7 +15,6 @@
<string name="shortcut_label">紧急</string>
<string name="wipe_on_inactivity_switch">在不使用时擦除</string>
<string name="wipe_on_inactivity_description">当设备在N天内没被解锁时擦除</string>
<string name="wipe_on_inactivity_days">天数</string>
<string name="notification_channel_default_name">默认设置</string>
<string name="wipe_job_description">擦除不使用的设备</string>
<string name="wipe_job_schedule_failed_popup">无法制定擦除计划</string>

View File

@ -1,13 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="wipe_on_inactivity_days">
<item>1</item>
<item>2</item>
<item>3</item>
<item>5</item>
<item>7</item>
<item>10</item>
<item>15</item>
<item>30</item>
</string-array>
</resources>

View File

@ -14,8 +14,10 @@
<string name="tile_label">Airplane mode</string>
<string name="shortcut_label">Panic</string>
<string name="wipe_on_inactivity_switch">Wipe on inactivity</string>
<string name="wipe_on_inactivity_description">Wipe a device when it was not unlocked for N days.</string>
<string name="wipe_on_inactivity_days">Days</string>
<string name="wipe_on_inactivity_description">Wipe a device when it was not unlocked for N time.</string>
<string name="wipe_on_inactivity_time_hint">time</string>
<string name="wipe_on_inactivity_time_error">7d / 48h / 120m</string>
<string name="wipe_on_inactivity_time_helper_text">[d]ays [h]ours [m]inutes</string>
<string name="notification_channel_default_name">Default</string>
<string name="wipe_job_description">Wipe a device on inactivity</string>
<string name="wipe_job_schedule_failed_popup">Failed to schedule a wipe job</string>

View File

@ -0,0 +1 @@
add custom wipe on inactivity timings

View File

@ -4,7 +4,7 @@ You can use PanicKit, tile, shortcut or send a message with authentication code.
Device Administration API, it locks a device and optionally runs wipe.
Also you can:
* wipe a device when it was not unlocked for N days
* wipe a device when it was not unlocked for N time
* wipe a device using a duress password (companion app: [Duress](https://github.com/x13a/Duress))
The app works in Work Profile too. Use Shelter to install risky apps and Wasted in it. Then you can

Binary file not shown.

Before

Width:  |  Height:  |  Size: 101 KiB

After

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 100 KiB