make wipe action optional

This commit is contained in:
lucky 2021-12-18 02:26:43 +03:00
parent 3e45fe0ca5
commit 5f772a6968
11 changed files with 46 additions and 18 deletions

View File

@ -1,6 +1,6 @@
# Wasted # Wasted
Wipe data on panic trigger. Lock device and wipe data on panic trigger.
[<img src="https://fdroid.gitlab.io/artwork/badge/get-it-on.png" [<img src="https://fdroid.gitlab.io/artwork/badge/get-it-on.png"
alt="Get it on F-Droid" alt="Get it on F-Droid"
@ -17,8 +17,8 @@ locks device and runs wipe.
Broadcast message: Broadcast message:
```sh ```sh
$ adb shell am broadcast \ $ adb shell am broadcast \
-a me.lucky.wasted.action.ESCAPE \ -a me.lucky.wasted.action.TRIGGER \
-n me.lucky.wasted/.ControlReceiver \ -n me.lucky.wasted/.CodeReceiver \
-e code "b49a6576-0c27-4f03-b96b-da53501022ba" -e code "b49a6576-0c27-4f03-b96b-da53501022ba"
``` ```

View File

@ -34,12 +34,12 @@
</receiver> </receiver>
<receiver <receiver
android:name=".ControlReceiver" android:name=".CodeReceiver"
android:enabled="false" android:enabled="false"
android:exported="true" android:exported="true"
tools:ignore="ExportedReceiver"> tools:ignore="ExportedReceiver">
<intent-filter> <intent-filter>
<action android:name="me.lucky.wasted.action.ESCAPE" /> <action android:name="me.lucky.wasted.action.TRIGGER" />
</intent-filter> </intent-filter>
</receiver> </receiver>
</application> </application>

View File

@ -5,20 +5,22 @@ import android.content.BroadcastReceiver
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
class ControlReceiver : BroadcastReceiver() { class CodeReceiver : BroadcastReceiver() {
companion object { companion object {
private const val ESCAPE = "me.lucky.wasted.action.ESCAPE" private const val TRIGGER = "me.lucky.wasted.action.TRIGGER"
} }
override fun onReceive(context: Context, intent: Intent) { override fun onReceive(context: Context, intent: Intent) {
val prefs by lazy { Preferences(context) } val prefs by lazy { Preferences(context) }
if (intent.action != ESCAPE || val code = prefs.code
!prefs.isServiceEnabled || if (!prefs.isServiceEnabled ||
intent.getStringExtra("code") != prefs.code) return code == "" ||
intent.action != TRIGGER ||
intent.getStringExtra("code") != code) return
val dpm = context.getSystemService(Context.DEVICE_POLICY_SERVICE) as DevicePolicyManager val dpm = context.getSystemService(Context.DEVICE_POLICY_SERVICE) as DevicePolicyManager
try { try {
dpm.lockNow() dpm.lockNow()
dpm.wipeData(0) if (prefs.doWipe) dpm.wipeData(0)
} catch (exc: SecurityException) {} } catch (exc: SecurityException) {}
} }
} }

View File

@ -57,6 +57,7 @@ class MainActivity : AppCompatActivity() {
if (prefs.code == "") prefs.code = makeCode() if (prefs.code == "") prefs.code = makeCode()
binding.apply { binding.apply {
code.text = prefs.code code.text = prefs.code
wipeDataCheckBox.isChecked = prefs.doWipe
toggle.isChecked = prefs.isServiceEnabled toggle.isChecked = prefs.isServiceEnabled
} }
} }
@ -68,6 +69,9 @@ class MainActivity : AppCompatActivity() {
code.text = prefs.code code.text = prefs.code
true true
} }
wipeDataCheckBox.setOnCheckedChangeListener { _, isChecked ->
prefs.doWipe = isChecked
}
toggle.setOnCheckedChangeListener { _, isChecked -> toggle.setOnCheckedChangeListener { _, isChecked ->
when (isChecked) { when (isChecked) {
true -> if (!isAdminActive()) requestAdmin() else setOn() true -> if (!isAdminActive()) requestAdmin() else setOn()
@ -104,7 +108,7 @@ class MainActivity : AppCompatActivity() {
private fun setControlReceiverState(ctx: Context, value: Boolean) { private fun setControlReceiverState(ctx: Context, value: Boolean) {
ctx.packageManager.setComponentEnabledSetting( ctx.packageManager.setComponentEnabledSetting(
ComponentName(ctx, ControlReceiver::class.java), ComponentName(ctx, CodeReceiver::class.java),
if (value) PackageManager.COMPONENT_ENABLED_STATE_ENABLED else if (value) PackageManager.COMPONENT_ENABLED_STATE_ENABLED else
PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
PackageManager.DONT_KILL_APP, PackageManager.DONT_KILL_APP,

View File

@ -10,6 +10,7 @@ class Preferences(ctx: Context) {
companion object { companion object {
private const val SERVICE_ENABLED = "service_enabled" private const val SERVICE_ENABLED = "service_enabled"
private const val CODE = "code" private const val CODE = "code"
private const val DO_WIPE = "do_wipe"
} }
private val mk = MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC) private val mk = MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC)
@ -28,4 +29,8 @@ class Preferences(ctx: Context) {
var code: String? var code: String?
get() = prefs.getString(CODE, "") get() = prefs.getString(CODE, "")
set(value) = prefs.edit { putString(CODE, value) } set(value) = prefs.edit { putString(CODE, value) }
var doWipe: Boolean
get() = prefs.getBoolean(DO_WIPE, false)
set(value) = prefs.edit { putBoolean(DO_WIPE, value) }
} }

View File

@ -35,8 +35,22 @@
android:id="@+id/toggle" android:id="@+id/toggle"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:paddingVertical="12dp"
android:textSize="16sp"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" /> app:layout_constraintStart_toStartOf="parent" />
<CheckBox
android:id="@+id/wipeDataCheckBox"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:layoutDirection="rtl"
android:text="@string/wipe_data_check_box"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/code" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -1,7 +1,8 @@
<resources> <resources>
<string name="app_name">Wasted</string> <string name="app_name">Wasted</string>
<string name="description">Turn on Wasted to wipe data on panic trigger. The app will listen for broadcast message with authentication code.</string> <string name="description">Turn on Wasted to lock device on panic trigger. The app will listen for broadcast message with this authentication code.</string>
<string name="device_admin_label">Wasted</string> <string name="device_admin_label">Wasted</string>
<string name="device_admin_description">Allow Wasted to wipe data on panic trigger</string> <string name="device_admin_description">Allow Wasted to lock device and wipe data on panic trigger</string>
<string name="service_unavailable_toast">Admin service unavailable</string> <string name="service_unavailable_toast">Admin service unavailable</string>
<string name="wipe_data_check_box">Wipe data</string>
</resources> </resources>

View File

@ -5,8 +5,8 @@ buildscript {
mavenCentral() mavenCentral()
} }
dependencies { dependencies {
classpath "com.android.tools.build:gradle:7.0.3" classpath 'com.android.tools.build:gradle:7.0.4'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.10"
// NOTE: Do not place your application dependencies here; they belong // NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files // in the individual module build.gradle files

View File

@ -1,2 +1,4 @@
Wipe data on panic trigger. Lock device and wipe data on panic trigger.
The app will listen for broadcast message with authentication code. The app will listen for broadcast message with authentication code.
On receive, using Device Administration API, it locks device and runs wipe.

View File

@ -1 +1 @@
Wipe data on panic trigger Lock device and wipe data on panic trigger