tile trigger safe delay option

This commit is contained in:
lucky 2022-07-09 09:29:05 +03:00
parent 07332d3892
commit b528d49c45
14 changed files with 151 additions and 21 deletions

View File

@ -22,7 +22,7 @@ message with a secret code. On trigger, using
locks a device and optionally runs wipe.
Also you can:
* fire when a device was not unlocked for N time
* fire when a device was not unlocked for X time
* fire when a USB data connection is made while a device is locked
* fire when a duress password is entered (companion app: [Duress](https://github.com/x13a/Duress))
@ -32,6 +32,12 @@ the whole device.
Only encrypted device may guarantee that the data will not be recoverable.
## Broadcast
* action: `me.lucky.wasted.action.TRIGGER`
* receiver: `me.lucky.wasted/.TriggerReceiver`
* also you have to send a secret code from Wasted with the key: `code`
## Permissions
* DEVICE_ADMIN - lock and optionally wipe a device

View File

@ -10,8 +10,8 @@ android {
applicationId "me.lucky.wasted"
minSdk 23
targetSdk 32
versionCode 30
versionName "1.5.1"
versionCode 31
versionName "1.5.2"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
@ -42,11 +42,13 @@ dependencies {
implementation 'androidx.core:core-ktx:1.8.0'
implementation 'androidx.appcompat:appcompat:1.4.2'
implementation 'com.google.android.material:material:1.6.1'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
implementation 'androidx.security:security-crypto:1.0.0'
implementation 'androidx.preference:preference-ktx:1.2.0'
implementation 'androidx.drawerlayout:drawerlayout:1.1.1'
implementation 'info.guardianproject.panic:panic:1.0'
}

View File

@ -3,7 +3,7 @@
xmlns:tools="http://schemas.android.com/tools"
package="me.lucky.wasted">
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-feature android:name="android.software.device_admin" android:required="true" />
<uses-feature android:name="android.hardware.usb.host" android:required="false" />

View File

@ -62,6 +62,7 @@ open class MainActivity : AppCompatActivity() {
private fun getFragment(id: Int) = when (id) {
R.id.nav_main -> MainFragment()
R.id.nav_trigger_tile -> TileFragment()
R.id.nav_trigger_lock -> LockFragment()
R.id.top_settings -> SettingsFragment()
else -> MainFragment()

View File

@ -12,6 +12,7 @@ import androidx.security.crypto.MasterKeys
class Preferences(ctx: Context, encrypted: Boolean = true) {
companion object {
private const val DEFAULT_TRIGGER_LOCK_COUNT = 7 * 24 * 60
private const val DEFAULT_TRIGGER_TILE_DELAY = 2000L
private const val ENABLED = "enabled"
private const val SECRET = "secret"
@ -20,6 +21,7 @@ class Preferences(ctx: Context, encrypted: Boolean = true) {
private const val TRIGGERS = "triggers"
private const val TRIGGER_LOCK_COUNT = "trigger_lock_count"
private const val TRIGGER_TILE_DELAY = "trigger_tile_delay"
private const val FILE_NAME = "sec_shared_prefs"
@ -79,6 +81,10 @@ class Preferences(ctx: Context, encrypted: Boolean = true) {
)
set(value) = prefs.edit { putInt(TRIGGER_LOCK_COUNT, value) }
var triggerTileDelay: Long
get() = prefs.getLong(TRIGGER_TILE_DELAY, DEFAULT_TRIGGER_TILE_DELAY)
set(value) = prefs.edit { putLong(TRIGGER_TILE_DELAY, value) }
fun registerListener(listener: SharedPreferences.OnSharedPreferenceChangeListener) =
prefs.registerOnSharedPreferenceChangeListener(listener)
@ -93,6 +99,7 @@ class Preferences(ctx: Context, encrypted: Boolean = true) {
when (v) {
is Boolean -> putBoolean(k, v)
is Int -> putInt(k, v)
is Long -> putLong(k, v)
is String -> putString(k, v)
}
}

View File

@ -57,13 +57,14 @@ class LockFragment : Fragment() {
ctx = requireContext()
prefs = Preferences(ctx)
prefsdb = Preferences(ctx, encrypted = false)
val count = prefs.triggerLockCount
val time = when {
count % (24 * 60) == 0 -> "${count / 24 / 60}$MODIFIER_DAYS"
count % 60 == 0 -> "${count / 60}$MODIFIER_HOURS"
else -> "$count$MODIFIER_MINUTES"
binding.apply {
val count = prefs.triggerLockCount
time.editText?.setText(when {
count % (24 * 60) == 0 -> "${count / 24 / 60}$MODIFIER_DAYS"
count % 60 == 0 -> "${count / 60}$MODIFIER_HOURS"
else -> "$count$MODIFIER_MINUTES"
})
}
binding.time.editText?.setText(time)
}
private fun setup() = binding.apply {

View File

@ -0,0 +1,62 @@
package me.lucky.wasted.fragment
import android.content.Context
import android.content.SharedPreferences
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import me.lucky.wasted.Preferences
import me.lucky.wasted.databinding.FragmentTileBinding
class TileFragment : Fragment() {
private lateinit var binding: FragmentTileBinding
private lateinit var ctx: Context
private lateinit var prefs: Preferences
private lateinit var prefsdb: Preferences
private val prefsListener = SharedPreferences.OnSharedPreferenceChangeListener { _, key ->
prefs.copyTo(prefsdb, key)
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?,
): View {
binding = FragmentTileBinding.inflate(inflater, container, false)
init()
setup()
return binding.root
}
override fun onStart() {
super.onStart()
prefs.registerListener(prefsListener)
}
override fun onStop() {
super.onStop()
prefs.unregisterListener(prefsListener)
}
private fun init() {
ctx = requireContext()
prefs = Preferences(ctx)
prefsdb = Preferences(ctx, encrypted = false)
binding.apply {
delay.value = prefs.triggerTileDelay.toFloat() / 1000
}
}
private fun setup() = binding.apply {
delay.setLabelFormatter {
String.format("%.1f", it)
}
delay.addOnChangeListener { _, value, _ ->
prefs.triggerTileDelay = (value * 1000).toLong()
}
}
}

View File

@ -13,10 +13,6 @@ import me.lucky.wasted.Trigger
@RequiresApi(Build.VERSION_CODES.N)
class TileService : TileService() {
companion object {
private const val SAFE_DELAY = 2000L
}
private lateinit var prefs: Preferences
private lateinit var admin: DeviceAdminManager
private var counter = 0
@ -61,7 +57,7 @@ class TileService : TileService() {
admin.lockNow()
admin.wipeData()
} catch (exc: SecurityException) {}
}, SAFE_DELAY)
}, prefs.triggerTileDelay)
}
else -> {
timer?.cancel()

View File

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".fragment.TileFragment">
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<com.google.android.material.slider.Slider
android:id="@+id/delay"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:stepSize="0.5"
android:valueFrom="0"
android:valueTo="3" />
<TextView
android:textAppearance="?attr/textAppearanceBodySmall"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/trigger_tile_delay_description" />
</LinearLayout>
</ScrollView>
</FrameLayout>

View File

@ -11,6 +11,10 @@
android:id="@+id/nav_group_options"
android:checkableBehavior="all">
<item
android:id="@+id/nav_trigger_tile"
android:title="@string/trigger_tile" />
<item
android:id="@+id/nav_trigger_lock"
android:title="@string/trigger_lock" />

View File

@ -1,18 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Wasted</string>
<string name="wipe_data_checkbox">Cancella i dati</string>
<string name="wipe_data_checkbox">Cancella dati</string>
<string name="wipe_embedded_sim_checkbox">Cancella eSIM</string>
<string name="panic_app_dialog_title">Conferma app di panico</string>
<string name="panic_app_dialog_message">Sei sicuro di voler consentire a %1$s di attivare azioni di panico distruttive\?</string>
<string name="panic_app_dialog_message">Sei sicuro di voler consentire a %1$s di attivare azioni di panico distruttive\\?</string>
<string name="panic_app_unknown_app">un\'app sconosciuta</string>
<string name="allow">Consenti</string>
<string name="tile_label">Modalità aereo</string>
<string name="shortcut_label">Panico</string>
<string name="trigger_lock_description">Cancella i dati quando il dispositivo non viene sbloccato per N tempo.</string>
<string name="trigger_lock_time_hint">tempo</string>
<string name="trigger_lock_time_error">7d / 48h / 120m</string>
<string name="trigger_lock_time_helper_text">[d]giorni [h]ore [m]minuti</string>
<string name="trigger_lock_time_helper_text">Quanto tempo aspettare. Modificatori: [d]giorni [h]ore [m]minuti</string>
<string name="notification_channel_default_name">Predefinito</string>
<string name="foreground_service_notification_title">Guardia</string>
<string name="trigger_panic_kit">PanicKit</string>
@ -20,5 +19,16 @@
<string name="trigger_shortcut">Scorciatoia</string>
<string name="trigger_broadcast">Broadcast</string>
<string name="trigger_notification">Notifica</string>
<string name="trigger_lock">Blocca</string>
<string name="trigger_usb">USB</string>
<string name="copied_popup">Copiato</string>
<string name="main">Principale</string>
<string name="settings">Impostazioni</string>
<string name="trigger_panic_kit_description">Abilita il panic responder. PanicKit è una raccolta di strumenti per la creazione di \"pulsanti di panico\" che possono attivare una risposta a livello di sistema quando l\'utente si trova in una situazione di ansia o di pericolo. Consente alle app trigger e alle app responder di connettersi tra loro in modo sicuro e semplice. L\'utente si collega all\'app trigger quando si trova in una situazione di panico. Le app di risposta ricevono il segnale di attivazione ed eseguono individualmente le operazioni per le quali sono state configurate.</string>
<string name="trigger_tile_description">Abilita il servizio toggle. Si tratta di un pulsante nel pannello delle impostazioni rapide quando scorri il dito dalla parte superiore dello schermo. Questo pulsante simula la modalità aereo. Ha un ritardo di due secondi se lo si tocca accidentalmente.</string>
<string name="trigger_shortcut_description">Abilita la scorciatoia dell\'icona. È un pulsante che viene visualizzato quando si tocca a lungo l\'icona di Wasted.</string>
<string name="trigger_broadcast_description">Abilita il ricevitore broadcast. È utile per comunicare con altre applicazioni Android. Ad esempio, è possibile avviare Wasted da Tasker.</string>
<string name="trigger_notification_description">Abilita l\'ascoltatore di notifiche del dispositivo. Esaminerà tutte le notifiche a cui ha accesso alla ricerca del codice segreto. Quando lo trova, si attiva. È necessario concedere a Wasted le autorizzazioni necessarie nelle Impostazioni &gt; Notifiche &gt; Notifiche app e dispositivi.</string>
<string name="trigger_lock_description">Abilita i Job Scheduler di blocco. Pianificherà un Job ogni volta che si blocca un dispositivo e lo annullerà ogni volta che si sblocca un dispositivo. Se non si sblocca un dispositivo per un periodo di tempo X, il Job verrà avviato.</string>
<string name="trigger_usb_description">Abilita il ricevitore di stato USB. Quando si effettua una connessione dati USB mentre un dispositivo è bloccato, il ricevitore si attiva. Non deve attivarsi sul caricatore, ma solo su dispositivi e accessori.</string>
</resources>

View File

@ -12,6 +12,7 @@
<string name="trigger_lock_time_hint">time</string>
<string name="trigger_lock_time_error">7d / 48h / 120m</string>
<string name="trigger_lock_time_helper_text">How much time to wait. Modifiers: [d]ays [h]ours [m]inutes</string>
<string name="trigger_tile_delay_description">Safe delay before it will fire. Gives you some time to cancel fire if you will tap a tile accidentally.</string>
<string name="notification_channel_default_name">Default</string>
<string name="foreground_service_notification_title">Guard</string>
<string name="trigger_panic_kit">PanicKit</string>
@ -25,7 +26,7 @@
<string name="main">Main</string>
<string name="settings">Settings</string>
<string name="trigger_panic_kit_description">Enable panic responder. PanicKit is a collection of tools for creating “panic buttons” that can trigger a system-wide response when the user is in an anxious or dangerous situation. It enables trigger apps and responder apps to safely and easily connect to each other. The user engages with the trigger app when in a panic situation. The responder apps receive that trigger signal, and individually execute the steps that they were configured to do.</string>
<string name="trigger_tile_description">Enable tile service. It is a button in quick settings panel when you swipe from the top of the screen. This button will mimic to the airplane mode. It has 2s delay if you will tap it accidentally.</string>
<string name="trigger_tile_description">Enable tile service. It is a button in quick settings panel when you swipe from the top of the screen. This button will mimic to the airplane mode.</string>
<string name="trigger_shortcut_description">Enable icon shortcut. It is a button you will see when you make a long tap on the Wasted icon.</string>
<string name="trigger_broadcast_description">Enable broadcast receiver. It is useful to communicate with another Android apps. For example you can fire Wasted from Tasker using this.</string>
<string name="trigger_notification_description">Enable device notification listener. It will scan all notifications it has access to for the secret code. When found it will fire. You have to give Wasted necessary permissions in Settings > Notifications > Device and app notifications.</string>

View File

@ -0,0 +1,2 @@
tile trigger safe delay option
update Italian translation, thanks to Giovanni Donisi (@gdonisi + @giovannidonisi)

View File

@ -4,7 +4,7 @@ You can use PanicKit, tile, shortcut or send a message with a secret code. On tr
Device Administration API, it locks a device and optionally runs wipe.
Also you can:
* fire when a device was not unlocked for N time
* fire when a device was not unlocked for X time
* fire when a USB data connection is made while a device is locked
* fire when a duress password is entered (companion app: [Duress](https://github.com/x13a/Duress))
@ -13,6 +13,11 @@ wipe this profile data with one click without wiping the whole device.
Only encrypted device may guarantee that the data will not be recoverable.
Broadcast:
* action: me.lucky.wasted.action.TRIGGER
* receiver: me.lucky.wasted/.TriggerReceiver
* also you have to send a secret code from Wasted with the key: code
Permissions:
* DEVICE_ADMIN - lock and optionally wipe a device
* FOREGROUND_SERVICE - receive lock and USB state events