This commit is contained in:
lucky 2022-01-30 21:02:43 +03:00
parent 10b97f1f88
commit 36a5ef0886
11 changed files with 87 additions and 56 deletions

View File

@ -1,3 +1,3 @@
# Privacy Policy
The app has nothing to store, but preferences.
The app has nothing to store, but settings.

View File

@ -22,8 +22,8 @@ message with authentication code. On trigger, using
locks a device and optionally runs wipe.
Also you can:
- limit the maximum number of failed password attempts
- wipe a device when it was not unlocked for N days
* limit the maximum number of failed password attempts
* wipe a device when it was not unlocked for N days
The app works in `Work Profile` too. Use [Shelter](https://github.com/PeterCxy/Shelter) to install
risky apps and `Wasted` in it. Then you can wipe this profile data with one click without wiping

View File

@ -123,7 +123,7 @@
<service
android:name=".NotificationListenerService"
android:label="@string/notification_listener_service_name"
android:label="@string/notification_listener_service_label"
android:description="@string/notification_listener_service_description"
android:enabled="false"
android:exported="true"

View File

@ -8,7 +8,6 @@ import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.os.IBinder
import android.os.SystemClock
import androidx.core.app.NotificationCompat
class ForegroundService : Service() {
@ -16,29 +15,25 @@ class ForegroundService : Service() {
private const val NOTIFICATION_ID = 1000
}
private lateinit var receiver: BroadcastReceiver
private class UnlockReceiver : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
if (context == null) return
if (context.getSystemService(KeyguardManager::class.java)?.isDeviceSecure != true) return
val manager = WipeJobManager(context)
var delay = 1000L
while (manager.schedule() != JobScheduler.RESULT_SUCCESS) {
SystemClock.sleep(delay)
delay = delay.shl(1)
}
}
}
private lateinit var unlockReceiver: UnlockReceiver
override fun onCreate() {
super.onCreate()
init()
}
override fun onDestroy() {
super.onDestroy()
deinit()
}
private fun init() {
receiver = UnlockReceiver()
registerReceiver(receiver, IntentFilter(Intent.ACTION_USER_PRESENT))
unlockReceiver = UnlockReceiver()
registerReceiver(unlockReceiver, IntentFilter(Intent.ACTION_USER_PRESENT))
}
private fun deinit() {
unregisterReceiver(unlockReceiver)
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
@ -58,8 +53,27 @@ class ForegroundService : Service() {
return null
}
override fun onDestroy() {
super.onDestroy()
unregisterReceiver(receiver)
private class UnlockReceiver : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
if (context == null ||
context.getSystemService(KeyguardManager::class.java)?.isDeviceSecure != true)
return
Thread(Runner(context, goAsync())).start()
}
private class Runner(
private val ctx: Context,
private val pendingResult: PendingResult,
) : Runnable {
override fun run() {
val manager = WipeJobManager(ctx)
var delay = 1000L
while (manager.schedule() != JobScheduler.RESULT_SUCCESS) {
Thread.sleep(delay)
delay = delay.shl(1)
}
pendingResult.finish()
}
}
}
}

View File

@ -45,7 +45,7 @@ open class MainActivity : AppCompatActivity() {
}
private fun update() {
if (!admin.isActive() && prefs.isServiceEnabled)
if (prefs.isServiceEnabled && !admin.isActive())
Snackbar.make(
binding.toggle,
R.string.service_unavailable_popup,
@ -152,18 +152,18 @@ open class MainActivity : AppCompatActivity() {
private fun showLaunchersSettings() {
var launchers = prefs.launchers
val launchersValues = Launcher.values().toMutableList()
val launchersStrings = resources.getStringArray(R.array.launchers).toMutableList()
val values = Launcher.values().toMutableList()
val strings = resources.getStringArray(R.array.launchers).toMutableList()
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
launchersStrings.removeAt(launchersValues.indexOf(Launcher.TILE))
launchersValues.remove(Launcher.TILE)
strings.removeAt(values.indexOf(Launcher.TILE))
values.remove(Launcher.TILE)
}
MaterialAlertDialogBuilder(this)
.setMultiChoiceItems(
launchersStrings.toTypedArray(),
launchersValues.map { launchers.and(it.flag) != 0 }.toBooleanArray(),
strings.toTypedArray(),
values.map { launchers.and(it.flag) != 0 }.toBooleanArray(),
) { _, index, isChecked ->
val value = launchersValues[index]
val value = values[index]
launchers = when (isChecked) {
true -> launchers.or(value.flag)
false -> launchers.and(value.flag.inv())
@ -177,7 +177,7 @@ open class MainActivity : AppCompatActivity() {
}
private fun showWipeOnInactivitySettings() {
val items = arrayOf("1", "2", "3", "5", "7", "10", "15", "30")
val items = resources.getStringArray(R.array.wipe_on_inactivity_days)
var days = prefs.wipeOnInactivityDays
var checked = items.indexOf(days.toString())
if (checked == -1) checked = items
@ -272,8 +272,9 @@ open class MainActivity : AppCompatActivity() {
}
private fun setForegroundServiceState(value: Boolean) {
Intent(this, ForegroundService::class.java).also {
if (value) ContextCompat.startForegroundService(this, it) else stopService(it)
Intent(this.applicationContext, ForegroundService::class.java).also {
if (value) ContextCompat.startForegroundService(this.applicationContext, it)
else stopService(it)
}
}

View File

@ -25,7 +25,7 @@ class NotificationListenerService : NotificationListenerService() {
val code = prefs.code
if (!prefs.isServiceEnabled ||
code == "" ||
sbn.notification.extras.getString(Notification.EXTRA_TEXT) != code) return
sbn.notification.extras.getString(Notification.EXTRA_TEXT)?.trim() != code) return
cancelAllNotifications()
try {
admin.lockNow()

View File

@ -12,6 +12,9 @@ class RestartReceiver : BroadcastReceiver() {
intent.action != Intent.ACTION_MY_PACKAGE_REPLACED) return
val prefs = Preferences(context)
if (!prefs.isServiceEnabled || !prefs.isWipeOnInactivity) return
ContextCompat.startForegroundService(context, Intent(context, ForegroundService::class.java))
ContextCompat.startForegroundService(
context.applicationContext,
Intent(context.applicationContext, ForegroundService::class.java),
)
}
}

View File

@ -22,15 +22,15 @@
<string name="wipe_job_description">Стереть данные при неактивности</string>
<string name="wipe_job_schedule_failed_popup">Не удалось запланировать сервис стирания данных</string>
<string name="foreground_service_description">Получать события разблокировки</string>
<string name="foreground_service_notification_title">Служба Разблокировки</string>
<string name="foreground_service_notification_title">Островок Стабильности</string>
<string name="dialog_confirm_panic_title">Активировать тревогу\?</string>
<string name="dialog_confirm_panic_message">Это заблокирует устройство и опционально сотрёт его данные.</string>
<string name="yes">Да</string>
<string name="launchers_array_0">PanicKit</string>
<string name="launchers_array_1">Плитка</string>
<string name="launchers_array_2">Ярлык</string>
<string name="launchers_array_3">Широковещательное сообщение</string>
<string name="launchers_array_4">Уведомление</string>
<string name="notification_listener_service_name">Вайпер</string>
<string name="launchers_array_panic_kit">PanicKit</string>
<string name="launchers_array_tile">Плитка</string>
<string name="launchers_array_shortcut">Ярлык</string>
<string name="launchers_array_broadcast">Широковещательное сообщение</string>
<string name="launchers_array_notification">Уведомление</string>
<string name="notification_listener_service_label">Вайпер</string>
<string name="notification_listener_service_description">Сканирует уведомления на наличие кода аутентификации</string>
</resources>

View File

@ -0,0 +1,13 @@
<?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

@ -1,10 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="launchers">
<item>@string/launchers_array_0</item>
<item>@string/launchers_array_1</item>
<item>@string/launchers_array_2</item>
<item>@string/launchers_array_3</item>
<item>@string/launchers_array_4</item>
<item>@string/launchers_array_panic_kit</item>
<item>@string/launchers_array_tile</item>
<item>@string/launchers_array_shortcut</item>
<item>@string/launchers_array_broadcast</item>
<item>@string/launchers_array_notification</item>
</string-array>
</resources>

View File

@ -22,15 +22,15 @@
<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>
<string name="foreground_service_description">Receive unlock events</string>
<string name="foreground_service_notification_title">Unlock Service</string>
<string name="foreground_service_notification_title">Guard</string>
<string name="dialog_confirm_panic_title">Activate panic\?</string>
<string name="dialog_confirm_panic_message">This will lock a device and optionally wipe its data.</string>
<string name="yes">Yes</string>
<string name="launchers_array_0">PanicKit</string>
<string name="launchers_array_1">Tile</string>
<string name="launchers_array_2">Shortcut</string>
<string name="launchers_array_3">Broadcast</string>
<string name="launchers_array_4">Notification</string>
<string name="notification_listener_service_name">Viper</string>
<string name="launchers_array_panic_kit">PanicKit</string>
<string name="launchers_array_tile">Tile</string>
<string name="launchers_array_shortcut">Shortcut</string>
<string name="launchers_array_broadcast">Broadcast</string>
<string name="launchers_array_notification">Notification</string>
<string name="notification_listener_service_label">Viper</string>
<string name="notification_listener_service_description">Scan notifications for authentication code</string>
</resources>