mirror of
https://github.com/rhunk/SnapEnhance.git
synced 2025-05-28 12:30:12 +02:00
feat(core): sif status
- add InAppOverlay custom composable
This commit is contained in:
parent
43f1a305a2
commit
0ac142f46c
@ -60,6 +60,7 @@ class FeatureManager(
|
||||
|
||||
fun init() {
|
||||
register(
|
||||
SecurityFeatures(),
|
||||
EndToEndEncryption(),
|
||||
ScopeSync(),
|
||||
PreventMessageListAutoScroll(),
|
||||
|
@ -0,0 +1,74 @@
|
||||
package me.rhunk.snapenhance.core.features.impl
|
||||
|
||||
import android.system.Os
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.withContext
|
||||
import me.rhunk.snapenhance.core.features.Feature
|
||||
|
||||
class SecurityFeatures : Feature("Security Features") {
|
||||
private fun transact(option: Int) = Os.prctl(option, 0, 0, 0, 0)
|
||||
|
||||
private val token by lazy {
|
||||
runCatching { transact(0) }.getOrNull()
|
||||
}
|
||||
|
||||
private fun getStatus() = token?.run {
|
||||
transact(this).toString(2).padStart(32, '0').count { it == '1' }
|
||||
}
|
||||
|
||||
override fun init() {
|
||||
token // pre init token
|
||||
|
||||
context.inAppOverlay.addCustomComposable {
|
||||
var statusText by remember {
|
||||
mutableStateOf("")
|
||||
}
|
||||
var textColor by remember {
|
||||
mutableStateOf(Color.Red)
|
||||
}
|
||||
|
||||
LaunchedEffect(Unit) {
|
||||
withContext(Dispatchers.IO) {
|
||||
while (true) {
|
||||
val status = getStatus()
|
||||
withContext(Dispatchers.Main) {
|
||||
if (status == null || status == 0) {
|
||||
textColor = Color.Red
|
||||
statusText = "sif not loaded. Can't get status"
|
||||
} else {
|
||||
textColor = Color.Green
|
||||
statusText = "sif = $status"
|
||||
}
|
||||
}
|
||||
delay(1000)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Text(
|
||||
text = statusText,
|
||||
modifier = Modifier
|
||||
.align(Alignment.BottomCenter)
|
||||
.background(Color.Black, shape = RoundedCornerShape(5.dp))
|
||||
.padding(3.dp),
|
||||
fontSize = 10.sp,
|
||||
color = textColor
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
@ -6,7 +6,6 @@ import android.content.Intent
|
||||
import android.database.sqlite.SQLiteDatabase
|
||||
import android.net.Uri
|
||||
import android.os.ParcelFileDescriptor
|
||||
import android.widget.FrameLayout
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.items
|
||||
@ -26,12 +25,12 @@ import kotlinx.coroutines.withContext
|
||||
import me.rhunk.snapenhance.common.data.FileType
|
||||
import me.rhunk.snapenhance.common.ui.AppMaterialTheme
|
||||
import me.rhunk.snapenhance.common.ui.createComposeAlertDialog
|
||||
import me.rhunk.snapenhance.common.ui.createComposeView
|
||||
import me.rhunk.snapenhance.common.util.ktx.toParcelFileDescriptor
|
||||
import me.rhunk.snapenhance.common.util.snap.MediaDownloaderHelper
|
||||
import me.rhunk.snapenhance.core.event.events.impl.ActivityResultEvent
|
||||
import me.rhunk.snapenhance.core.event.events.impl.AddViewEvent
|
||||
import me.rhunk.snapenhance.core.features.Feature
|
||||
import me.rhunk.snapenhance.core.ui.CustomComposable
|
||||
import me.rhunk.snapenhance.core.util.hook.HookStage
|
||||
import me.rhunk.snapenhance.core.util.hook.hook
|
||||
import me.rhunk.snapenhance.core.util.ktx.getId
|
||||
@ -507,24 +506,26 @@ class AccountSwitcher: Feature("Account Switcher") {
|
||||
}
|
||||
}
|
||||
|
||||
findClass("com.snap.identity.loginsignup.ui.LoginSignupActivity").apply {
|
||||
hook("onPostCreate", HookStage.AFTER) {
|
||||
context.mainActivity!!.findViewById<FrameLayout>(android.R.id.content).addView(createComposeView(context.mainActivity!!) {
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
) {
|
||||
Button(
|
||||
onClick = { showManagementPopup() },
|
||||
modifier = Modifier.padding(16.dp)
|
||||
) {
|
||||
Text("Switch Account")
|
||||
}
|
||||
}
|
||||
}.apply {
|
||||
layoutParams = FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT).apply {
|
||||
gravity = android.view.Gravity.TOP or android.view.Gravity.START
|
||||
}
|
||||
})
|
||||
val switchButtonComposable: CustomComposable = {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.align(Alignment.TopStart),
|
||||
) {
|
||||
Button(
|
||||
onClick = { showManagementPopup() },
|
||||
modifier = Modifier.padding(16.dp)
|
||||
) {
|
||||
Text("Switch Account")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onNextActivityCreate { activity ->
|
||||
if (!activity.componentName.className.endsWith("LoginSignupActivity")) return@onNextActivityCreate
|
||||
context.inAppOverlay.addCustomComposable(switchButtonComposable)
|
||||
onNextActivityCreate {
|
||||
context.inAppOverlay.removeCustomComposable(switchButtonComposable)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,26 +1,16 @@
|
||||
package me.rhunk.snapenhance.core.features.impl.experiments
|
||||
|
||||
import android.app.Activity
|
||||
import android.view.View
|
||||
import android.widget.FrameLayout
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.BugReport
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.FilledIconButton
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextField
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.text.TextStyle
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
@ -29,9 +19,7 @@ import androidx.compose.ui.unit.sp
|
||||
import kotlinx.coroutines.launch
|
||||
import me.rhunk.snapenhance.common.bridge.FileHandleScope
|
||||
import me.rhunk.snapenhance.common.bridge.toWrapper
|
||||
import me.rhunk.snapenhance.common.ui.AppMaterialTheme
|
||||
import me.rhunk.snapenhance.common.ui.createComposeAlertDialog
|
||||
import me.rhunk.snapenhance.common.ui.createComposeView
|
||||
import me.rhunk.snapenhance.core.features.Feature
|
||||
import me.rhunk.snapenhance.core.features.impl.downloader.MediaDownloader
|
||||
import me.rhunk.snapenhance.core.util.hook.HookStage
|
||||
@ -101,35 +89,6 @@ class ComposerHooks: Feature("ComposerHooks") {
|
||||
}
|
||||
}
|
||||
|
||||
private val composerConsoleTag = Random.nextLong().toString()
|
||||
|
||||
private fun injectConsole(activity: Activity) {
|
||||
val root = activity.findViewById<FrameLayout>(android.R.id.content) ?: run {
|
||||
context.log.warn("Unable to find root view. Can't inject console.")
|
||||
return
|
||||
}
|
||||
root.post {
|
||||
if (root.findViewWithTag<View>(composerConsoleTag) != null) return@post
|
||||
root.addView(createComposeView(root.context) {
|
||||
AppMaterialTheme {
|
||||
FilledIconButton(
|
||||
onClick = {
|
||||
composerConsole.show()
|
||||
},
|
||||
modifier = Modifier.padding(top = 100.dp, end = 16.dp)
|
||||
) {
|
||||
Icon(Icons.Default.BugReport, contentDescription = "Debug Console")
|
||||
}
|
||||
}
|
||||
}.apply {
|
||||
tag = composerConsoleTag
|
||||
layoutParams = FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT).apply {
|
||||
gravity = android.view.Gravity.TOP or android.view.Gravity.END
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
private fun newComposerFunction(block: ComposerMarshaller.() -> Boolean): Any? {
|
||||
val composerFunctionClass = findClass("com.snap.composer.callable.ComposerFunction")
|
||||
return Proxy.newProxyInstance(
|
||||
@ -223,9 +182,16 @@ class ComposerHooks: Feature("ComposerHooks") {
|
||||
|
||||
loadHooks()
|
||||
|
||||
onNextActivityCreate { activity ->
|
||||
if (config.composerConsole.get()) {
|
||||
injectConsole(activity)
|
||||
if (config.composerConsole.get()) {
|
||||
context.inAppOverlay.addCustomComposable {
|
||||
FilledIconButton(
|
||||
onClick = {
|
||||
composerConsole.show()
|
||||
},
|
||||
modifier = Modifier.align(Alignment.TopEnd).padding(top = 100.dp, end = 16.dp)
|
||||
) {
|
||||
Icon(Icons.Default.BugReport, contentDescription = "Debug Console")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -40,6 +40,8 @@ import me.rhunk.snapenhance.core.util.ktx.isDarkTheme
|
||||
import kotlin.math.roundToInt
|
||||
import kotlin.random.Random
|
||||
|
||||
typealias CustomComposable = @Composable BoxScope.() -> Unit
|
||||
|
||||
class InAppOverlay(
|
||||
private val context: ModContext
|
||||
) {
|
||||
@ -113,6 +115,7 @@ class InAppOverlay(
|
||||
}
|
||||
|
||||
private val toasts = mutableStateListOf<Toast>()
|
||||
private val customComposables = mutableStateListOf<CustomComposable>()
|
||||
|
||||
@OptIn(ExperimentalFoundationApi::class)
|
||||
@Composable
|
||||
@ -180,6 +183,10 @@ class InAppOverlay(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
customComposables.forEach {
|
||||
it()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -204,6 +211,14 @@ class InAppOverlay(
|
||||
injectOverlay(activity)
|
||||
}
|
||||
|
||||
fun addCustomComposable(composable: CustomComposable) {
|
||||
customComposables.add(composable)
|
||||
}
|
||||
|
||||
fun removeCustomComposable(composable: CustomComposable) {
|
||||
customComposables.remove(composable)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun DurationProgress(
|
||||
duration: Int,
|
||||
|
Loading…
x
Reference in New Issue
Block a user