diff --git a/README.md b/README.md
index 539da16..3677543 100644
--- a/README.md
+++ b/README.md
@@ -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
diff --git a/SECURITY.md b/SECURITY.md
index 5cddaaa..90eec2c 100644
--- a/SECURITY.md
+++ b/SECURITY.md
@@ -9,4 +9,4 @@
## Reporting a Vulnerability
-Contact: mailto:44uaanjm0@relay.firefox.com
+Contact: 44uaanjm0@relay.firefox.com
diff --git a/app/build.gradle b/app/build.gradle
index 0b59314..fa940c7 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -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"
}
diff --git a/app/src/main/java/me/lucky/wasted/MainActivity.kt b/app/src/main/java/me/lucky/wasted/MainActivity.kt
index 66c6b8f..499b829 100644
--- a/app/src/main/java/me/lucky/wasted/MainActivity.kt
+++ b/app/src/main/java/me/lucky/wasted/MainActivity.kt
@@ -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
diff --git a/app/src/main/res/drawable/ic_baseline_check_circle_24.xml b/app/src/main/res/drawable/ic_baseline_check_circle_24.xml
new file mode 100644
index 0000000..b83d1bc
--- /dev/null
+++ b/app/src/main/res/drawable/ic_baseline_check_circle_24.xml
@@ -0,0 +1,5 @@
+
+
+
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
index 72c84e2..8f5d226 100644
--- a/app/src/main/res/layout/activity_main.xml
+++ b/app/src/main/res/layout/activity_main.xml
@@ -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" />
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml
index 171b266..073aefd 100644
--- a/app/src/main/res/values-de/strings.xml
+++ b/app/src/main/res/values-de/strings.xml
@@ -15,7 +15,6 @@
Panik
Bei Inaktivität löschen
Den Speicher des Geräts löschen, wenn es für N Tage nicht entsperrt wurde.
- Tage
Standard
Den Speicher bei Inaktivität löschen
Fehler bei der Durchführung des Wipes
diff --git a/app/src/main/res/values-es-rES/strings.xml b/app/src/main/res/values-es-rES/strings.xml
index bbad40a..d0a949d 100644
--- a/app/src/main/res/values-es-rES/strings.xml
+++ b/app/src/main/res/values-es-rES/strings.xml
@@ -15,7 +15,6 @@
Pánico
Borrar por inactividad
Limpia un dispositivo cuando no fue desbloqueado por N días.
- Días
Predeterminado
Borrar un dispositivo por inactividad
Error al programar un trabajo de borrado
diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml
index f4d69d1..e0bd6f7 100644
--- a/app/src/main/res/values-it/strings.xml
+++ b/app/src/main/res/values-it/strings.xml
@@ -15,7 +15,6 @@
Panico
Cancella in caso di inattività
Cancella i dati quando il dispositivo non viene sbloccato per N giorni.
- Giorni
Predefinito
Cancella i dati in caso di inattività
Impossibile pianificare un processo di cancellazione
diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml
index de7be17..521d906 100644
--- a/app/src/main/res/values-ru/strings.xml
+++ b/app/src/main/res/values-ru/strings.xml
@@ -15,7 +15,6 @@
Тревога
Стереть при неактивности
Стереть данные когда устройство не разблокируется N дней.
- Дней
По умолчанию
Стереть данные при неактивности
Не удалось запланировать сервис стирания данных
diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml
index 14803d6..1f59349 100644
--- a/app/src/main/res/values-tr/strings.xml
+++ b/app/src/main/res/values-tr/strings.xml
@@ -15,7 +15,6 @@
Panik
Kullanılmadığında sil
N gün boyunca kilidi açılmamış bir cihazı silin.
- Gün
Varsayılan
Cihaz kullanılmadığında siler
Silme işi zamanlanamadı
diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml
index fab2407..23a1565 100644
--- a/app/src/main/res/values-uk/strings.xml
+++ b/app/src/main/res/values-uk/strings.xml
@@ -15,7 +15,6 @@
Тривога
Wipe on inactivity
Видалення пристрою, коли його не було розблоковано протягом N днів.
- Днів
За замовчуванням
Wipe a device on inactivity
Failed to schedule a wipe job
diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml
index 7ded256..035437d 100644
--- a/app/src/main/res/values-zh-rCN/strings.xml
+++ b/app/src/main/res/values-zh-rCN/strings.xml
@@ -15,7 +15,6 @@
紧急
在不使用时擦除
当设备在N天内没被解锁时擦除
- 天数
默认设置
擦除不使用的设备
无法制定擦除计划
diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml
deleted file mode 100644
index 4db1e11..0000000
--- a/app/src/main/res/values/arrays.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
- - 1
- - 2
- - 3
- - 5
- - 7
- - 10
- - 15
- - 30
-
-
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 06f6e5b..dbec6a7 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -14,8 +14,10 @@
Airplane mode
Panic
Wipe on inactivity
- Wipe a device when it was not unlocked for N days.
- Days
+ Wipe a device when it was not unlocked for N time.
+ time
+ 7d / 48h / 120m
+ [d]ays [h]ours [m]inutes
Default
Wipe a device on inactivity
Failed to schedule a wipe job
diff --git a/fastlane/metadata/android/en-US/changelogs/26.txt b/fastlane/metadata/android/en-US/changelogs/26.txt
new file mode 100644
index 0000000..9244f92
--- /dev/null
+++ b/fastlane/metadata/android/en-US/changelogs/26.txt
@@ -0,0 +1 @@
+add custom wipe on inactivity timings
diff --git a/fastlane/metadata/android/en-US/full_description.txt b/fastlane/metadata/android/en-US/full_description.txt
index 3c93ad3..51c4fbe 100644
--- a/fastlane/metadata/android/en-US/full_description.txt
+++ b/fastlane/metadata/android/en-US/full_description.txt
@@ -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
diff --git a/fastlane/metadata/android/en-US/images/phoneScreenshots/1.png b/fastlane/metadata/android/en-US/images/phoneScreenshots/1.png
index 5828436..b016d6a 100644
Binary files a/fastlane/metadata/android/en-US/images/phoneScreenshots/1.png and b/fastlane/metadata/android/en-US/images/phoneScreenshots/1.png differ
diff --git a/fastlane/metadata/android/en-US/images/phoneScreenshots/3.png b/fastlane/metadata/android/en-US/images/phoneScreenshots/3.png
deleted file mode 100644
index 950510e..0000000
Binary files a/fastlane/metadata/android/en-US/images/phoneScreenshots/3.png and /dev/null differ