commit 2aac63ef7a1a18635ece0a79145c1419d218ad37
parent bcaa7b78ae52cbceb91d3b4897469dbb92ead34e
Author: rhunk <101876869+rhunk@users.noreply.github.com>
Date: Sun, 28 May 2023 09:11:01 +0200
feat: app passcode
Diffstat:
5 files changed, 118 insertions(+), 4 deletions(-)
diff --git a/app/src/main/assets/lang/en_US.json b/app/src/main/assets/lang/en_US.json
@@ -54,6 +54,8 @@
"streak_expiration_info": "Show Streak Expiration Info",
"new_map_ui": "New Map UI",
"use_download_manager": "Use Android Download Manager",
+ "app_passcode": "Set App Passcode",
+ "app_lock_on_resume": "App Lock On Resume",
"meo_passcode_bypass": "My Eyes Only Passcode Bypass"
},
diff --git a/app/src/main/kotlin/me/rhunk/snapenhance/bridge/service/MainActivity.kt b/app/src/main/kotlin/me/rhunk/snapenhance/bridge/service/MainActivity.kt
@@ -8,10 +8,6 @@ import me.rhunk.snapenhance.Constants
class MainActivity : Activity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
- if (intent.getBooleanExtra("is_from_bridge", false)) {
- finish()
- return
- }
packageManager.getLaunchIntentForPackage(Constants.SNAPCHAT_PACKAGE_NAME)?.apply {
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
startActivity(this)
diff --git a/app/src/main/kotlin/me/rhunk/snapenhance/config/ConfigProperty.kt b/app/src/main/kotlin/me/rhunk/snapenhance/config/ConfigProperty.kt
@@ -213,6 +213,18 @@ enum class ConfigProperty(
ConfigCategory.EXPERIMENTAL,
ConfigStateValue(false)
),
+ APP_PASSCODE(
+ "property.app_passcode",
+ "description.app_passcode",
+ ConfigCategory.EXPERIMENTAL,
+ ConfigStringValue("")
+ ),
+ APP_LOCK_ON_RESUME(
+ "property.app_lock_on_resume",
+ "description.app_lock_on_resume",
+ ConfigCategory.EXPERIMENTAL,
+ ConfigStateValue(false)
+ ),
MEO_PASSCODE_BYPASS(
"property.meo_passcode_bypass",
"description.meo_passcode_bypass",
diff --git a/app/src/main/kotlin/me/rhunk/snapenhance/features/impl/extras/AppPasscode.kt b/app/src/main/kotlin/me/rhunk/snapenhance/features/impl/extras/AppPasscode.kt
@@ -0,0 +1,101 @@
+package me.rhunk.snapenhance.features.impl.extras
+
+import android.annotation.SuppressLint
+import android.app.AlertDialog
+import android.content.Context
+import android.os.Build
+import android.text.Editable
+import android.text.InputType
+import android.text.TextWatcher
+import android.view.inputmethod.InputMethodManager
+import android.widget.EditText
+import me.rhunk.snapenhance.config.ConfigProperty
+import me.rhunk.snapenhance.features.Feature
+import me.rhunk.snapenhance.features.FeatureLoadParams
+
+//TODO: fingerprint unlock
+class AppPasscode : Feature("App Passcode", loadParams = FeatureLoadParams.ACTIVITY_CREATE_SYNC) {
+ private var isLocked = false
+
+ private fun setActivityVisibility(isVisible: Boolean) {
+ context.mainActivity?.let {
+ it.window.attributes = it.window.attributes.apply { alpha = if (isVisible) 1.0F else 0.0F }
+ }
+ }
+
+ fun lock() {
+ if (isLocked) return
+ isLocked = true
+ val passcode = context.config.string(ConfigProperty.APP_PASSCODE).also { if (it.isEmpty()) return }
+ val isDigitPasscode = passcode.all { it.isDigit() }
+
+ val mainActivity = context.mainActivity!!
+ setActivityVisibility(false)
+
+ val prompt = AlertDialog.Builder(mainActivity)
+ val createPrompt = {
+ val alertDialog = prompt.create()
+ val textView = EditText(mainActivity)
+ textView.setSingleLine()
+ textView.inputType = if (isDigitPasscode) InputType.TYPE_CLASS_NUMBER else InputType.TYPE_CLASS_TEXT
+ textView.hint = "Code :"
+ textView.setPadding(100, 100, 100, 100)
+
+ textView.addTextChangedListener(object: TextWatcher {
+ override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
+ if (s.contentEquals(passcode)) {
+ alertDialog.dismiss()
+ isLocked = false
+ setActivityVisibility(true)
+ }
+ }
+ override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
+ override fun afterTextChanged(s: Editable?) {}
+ })
+
+ alertDialog.setView(textView)
+
+ textView.viewTreeObserver.addOnWindowFocusChangeListener { hasFocus ->
+ if (!hasFocus) return@addOnWindowFocusChangeListener
+ val imm = mainActivity.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
+ imm.showSoftInput(textView, InputMethodManager.SHOW_IMPLICIT)
+ }
+
+ alertDialog.window?.let {
+ it.attributes.verticalMargin = -0.18F
+ }
+
+ alertDialog.show()
+ textView.requestFocus()
+ }
+
+ prompt.setOnCancelListener {
+ createPrompt()
+ }
+
+ createPrompt()
+ }
+
+ @SuppressLint("MissingPermission")
+ override fun onActivityCreate() {
+ if (!context.database.hasArroyo()) return
+
+ context.runOnUiThread {
+ lock()
+ }
+
+ if (!context.config.bool(ConfigProperty.APP_LOCK_ON_RESUME)) return
+
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
+ context.mainActivity?.registerActivityLifecycleCallbacks(object: android.app.Application.ActivityLifecycleCallbacks {
+ override fun onActivityPaused(activity: android.app.Activity) { lock() }
+ override fun onActivityResumed(activity: android.app.Activity) {}
+ override fun onActivityStarted(activity: android.app.Activity) {}
+ override fun onActivityDestroyed(activity: android.app.Activity) {}
+ override fun onActivitySaveInstanceState(activity: android.app.Activity, outState: android.os.Bundle) {}
+ override fun onActivityStopped(activity: android.app.Activity) {}
+ override fun onActivityCreated(activity: android.app.Activity, savedInstanceState: android.os.Bundle?) {}
+ })
+ }
+ }
+}+
\ No newline at end of file
diff --git a/app/src/main/kotlin/me/rhunk/snapenhance/manager/impl/FeatureManager.kt b/app/src/main/kotlin/me/rhunk/snapenhance/manager/impl/FeatureManager.kt
@@ -10,6 +10,7 @@ import me.rhunk.snapenhance.features.impl.Messaging
import me.rhunk.snapenhance.features.impl.downloader.AntiAutoDownload
import me.rhunk.snapenhance.features.impl.downloader.MediaDownloader
import me.rhunk.snapenhance.features.impl.extras.AntiAutoSave
+import me.rhunk.snapenhance.features.impl.extras.AppPasscode
import me.rhunk.snapenhance.features.impl.extras.AutoSave
import me.rhunk.snapenhance.features.impl.extras.DisableVideoLengthRestriction
import me.rhunk.snapenhance.features.impl.extras.GalleryMediaSendOverride
@@ -72,6 +73,7 @@ class FeatureManager(private val context: ModContext) : Manager {
register(DisableVideoLengthRestriction::class)
register(MediaQualityLevelOverride::class)
register(MeoPasscodeBypass::class)
+ register(AppPasscode::class)
initializeFeatures()
}