6.6.1 - Alpha3 - 新增 currentComponent 方法; 提升 currentPackage/currentActivity 识别准确性

This commit is contained in:
SuperMonster003
2025-01-01 11:51:06 +08:00
parent 5fafa21f0b
commit 42f36d9223
23 changed files with 323 additions and 117 deletions

View File

@@ -8,4 +8,9 @@ interface IUserService {
String execCommand(String command) = 2;
String currentPackage() = 11;
String currentActivity() = 12;
String currentComponent() = 13;
String currentComponentShort() = 14;
}

View File

@@ -1,58 +1,77 @@
package org.autojs.autojs.core.shizuku;
package org.autojs.autojs.core.shizuku
import android.content.Context;
import android.os.RemoteException;
import android.util.Log;
import android.app.ActivityManager
import android.content.ComponentName
import android.content.Context
import android.os.RemoteException
import android.util.Log
import androidx.annotation.Keep
import org.autojs.autojs.runtime.api.AbstractShell
import org.autojs.autojs.runtime.api.ProcessShell
import androidx.annotation.Keep;
class UserService : IUserService.Stub {
import org.autojs.autojs.runtime.api.AbstractShell;
import org.autojs.autojs.runtime.api.ProcessShell;
private var mContext: Context? = null
public class UserService extends IUserService.Stub {
@Suppress("DEPRECATION")
private val currentActivity: ComponentName?
get() {
val manager = mContext?.getSystemService(ActivityManager::class.java) ?: return null
val tasks = manager.getRunningTasks(1) ?: return null
if (tasks.isEmpty()) return null
return tasks[0].topActivity
}
/**
* Constructor is required.
*/
public UserService() {
Log.i("UserService", "constructor");
constructor() {
Log.i("UserService", "constructor")
}
/**
* Constructor with Context. This is only available from Shizuku API v13.
* <p>
* This method need to be annotated with {@link Keep} to prevent ProGuard from removing it.
*
*
* This method need to be annotated with [Keep] to prevent ProGuard from removing it.
*
* @param context Context created with createPackageContextAsUser
* @see <a href="https://github.com/RikkaApps/Shizuku-API/blob/672f5efd4b33c2441dbf609772627e63417587ac/server-shared/src/main/java/rikka/shizuku/server/UserService.java#L66">code used to create the instance of this class</a>
* @see [code used to create the instance of this class](https://github.com/RikkaApps/Shizuku-API/blob/672f5efd4b33c2441dbf609772627e63417587ac/server-shared/src/main/java/rikka/shizuku/server/UserService.java.L66)
*/
@Keep
public UserService(Context context) {
Log.i("UserService", "constructor with Context: context=" + context.toString());
constructor(context: Context) {
Log.i("UserService", "constructor with Context: context=$context")
mContext = context
}
/**
* Reserved destroy method
*/
@Override
public void destroy() {
Log.i("UserService", "destroy");
override fun destroy() {
Log.i("UserService", "destroy")
}
@Override
public void exit() {
destroy();
override fun exit() {
destroy()
}
@Override
public String execCommand(String command) throws RemoteException {
try {
return ProcessShell
.execCommand(command.split("\n"), ProcessShell.getShellProcess())
.toJson();
} catch (Exception e) {
return new AbstractShell.Result(1, e).toJson();
@Throws(RemoteException::class)
override fun execCommand(command: String): String {
return try {
ProcessShell
.execCommand(command.split("\n".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray(), ProcessShell.getShellProcess())
.toJson()
} catch (e: Exception) {
AbstractShell.Result(1, e).toJson()
}
}
override fun currentPackage() = currentActivity?.packageName ?: ""
override fun currentActivity() = currentActivity?.className ?: ""
override fun currentComponent() = currentActivity?.flattenToString() ?: ""
override fun currentComponentShort() = currentActivity?.flattenToShortString() ?: ""
}

View File

@@ -195,6 +195,7 @@ open class RhinoJavaScriptEngine(private val scriptRuntime: ScriptRuntime, priva
if (this is AutoJsContext) {
rhinoJavaScriptEngine = this@RhinoJavaScriptEngine
}
@Suppress("DEPRECATION")
optimizationLevel = -1
languageVersion = Context.VERSION_ES6
locale = Locale.getDefault()

View File

@@ -53,6 +53,7 @@ open class AndroidContextFactory(private val cacheDirectory: File) : ContextFact
private fun setupContext(context: Context) {
context.apply {
instructionObserverThreshold = 10000
@Suppress("DEPRECATION")
optimizationLevel = -1
languageVersion = Context.VERSION_ES6
locale = Locale.getDefault()

View File

@@ -67,30 +67,24 @@ public class Shell extends AbstractShell {
private volatile boolean mInitialized = false;
private volatile boolean mWaitingExit = false;
private volatile String mCommandOutput = null;
private final boolean mShouldReadOutput;
private Callback mCallback;
public Shell(Context context, boolean root) {
super(context, root);
}
public Shell(Context context) {
this(context, false);
}
public Shell(Context context, boolean root) {
this(context, root, true);
}
public Shell(Context context, boolean root, boolean shouldReadOutput) {
super(context, root);
mShouldReadOutput = shouldReadOutput;
public Shell(boolean root) {
this(ScriptRuntime.getApplicationContext(), root);
}
public Shell() {
this(false);
}
public Shell(boolean root) {
this(ScriptRuntime.getApplicationContext(), root);
}
@Override
protected void init(final String initialCommand) {
Handler uiHandler = new Handler(mContext.getMainLooper());

View File

@@ -53,10 +53,8 @@ object WrappedShizuku {
}
private val mUserServiceArgs = Shizuku.UserServiceArgs(ComponentName(BuildConfig.APPLICATION_ID, UserService::class.java.name))
.processNameSuffix("shizuku-service-for-${BuildConfig.APPLICATION_ID.substringAfterLast(".")}")
.daemon(false)
.processNameSuffix("service-for-${BuildConfig.APPLICATION_ID.split(".").lastOrNull() ?: BuildConfig.APPLICATION_ID}")
.debuggable(BuildConfig.DEBUG)
.version(BuildConfig.VERSION_CODE)
private val mBinderReceivedListener = Shizuku.OnBinderReceivedListener {
if (Shizuku.isPreV11()) {

View File

@@ -31,6 +31,27 @@ import java.util.function.Supplier
@Suppress("unused", "UNUSED_PARAMETER")
class Auto(private val scriptRuntime: ScriptRuntime) : Augmentable(scriptRuntime), Invokable {
override val selfAssignmentFunctions = listOf(
::start.name,
::stop.name,
::isRunning.name,
::exists.name,
::stateListener.name,
::registerEvent.name,
::registerEvents.name,
::removeEvent.name,
::removeEvents.name,
::waitFor.name,
::setMode.name,
::setFlags.name,
::setWindowFilter.name,
::launchSettings.name,
::clearCache.name,
::currentPackage.name,
::currentActivity.name,
::currentComponent.name,
)
override val selfAssignmentGetters = listOf<Pair<String, Supplier<Any?>>>(
"service" to Supplier {
scriptRuntime.accessibilityBridge.service
@@ -52,24 +73,6 @@ class Auto(private val scriptRuntime: ScriptRuntime) : Augmentable(scriptRuntime
},
)
override val selfAssignmentFunctions = listOf(
::start.name,
::stop.name,
::isRunning.name,
::exists.name,
::stateListener.name,
::registerEvent.name,
::registerEvents.name,
::removeEvent.name,
::removeEvents.name,
::waitFor.name,
::setMode.name,
::setFlags.name,
::setWindowFilter.name,
::launchSettings.name,
::clearCache.name,
)
override fun invoke(vararg args: Any?): Any = ensureArgumentsAtMost(args, 2) {
when {
it.isEmpty() -> invoke(null)
@@ -134,21 +137,22 @@ class Auto(private val scriptRuntime: ScriptRuntime) : Augmentable(scriptRuntime
@RhinoRuntimeFunctionInterface
fun stateListener(scriptRuntime: ScriptRuntime, args: Array<out Any?>): Undefined = ensureArgumentsAtMost(args, 1) {
val (listener) = it
scriptRuntime.accessibilityBridge.setAccessibilityListener(when {
listener.isJsNullish() -> null
listener is AccessibilityServiceCallback -> listener
listener is ScriptableObject -> {
val adapter = NativeJavaObject.createInterfaceAdapter(
AccessibilityServiceCallback::class.java, listener
) as AccessibilityServiceCallback
scriptRuntime.accessibilityBridge.setAccessibilityListener(
when {
listener.isJsNullish() -> null
listener is AccessibilityServiceCallback -> listener
listener is ScriptableObject -> {
val adapter = NativeJavaObject.createInterfaceAdapter(
AccessibilityServiceCallback::class.java, listener
) as AccessibilityServiceCallback
object : AccessibilityServiceCallback {
override fun onConnected() = adapter.onConnected()
override fun onDisconnected() = adapter.onDisconnected()
object : AccessibilityServiceCallback {
override fun onConnected() = adapter.onConnected()
override fun onDisconnected() = adapter.onDisconnected()
}
}
}
else -> throw WrappedIllegalArgumentException("Argument listener ($listener) is invalid for auto.setWindowFilter")
})
else -> throw WrappedIllegalArgumentException("Argument listener ($listener) is invalid for auto.setWindowFilter")
})
UNDEFINED
}
@@ -157,19 +161,20 @@ class Auto(private val scriptRuntime: ScriptRuntime) : Augmentable(scriptRuntime
fun registerEvent(scriptRuntime: ScriptRuntime, args: Array<out Any?>) = ensureArgumentsLength(args, 2) {
val (name, listener) = it
require(!name.isJsNullish()) { "Argument \"name\" for auto.registerEvent cannot be nullish" }
scriptRuntime.automator.registerEvent(Context.toString(name), when {
listener.isJsNullish() -> null
listener is AccessibilityEventCallback -> listener
listener is ScriptableObject -> {
val adapter = NativeJavaObject.createInterfaceAdapter(
AccessibilityEventCallback::class.java, listener
) as AccessibilityEventCallback
object : AccessibilityEventCallback {
override fun onAccessibilityEvent(event: AccessibilityEventWrapper) = adapter.onAccessibilityEvent(event)
scriptRuntime.automator.registerEvent(
Context.toString(name), when {
listener.isJsNullish() -> null
listener is AccessibilityEventCallback -> listener
listener is ScriptableObject -> {
val adapter = NativeJavaObject.createInterfaceAdapter(
AccessibilityEventCallback::class.java, listener
) as AccessibilityEventCallback
object : AccessibilityEventCallback {
override fun onAccessibilityEvent(event: AccessibilityEventWrapper) = adapter.onAccessibilityEvent(event)
}
}
}
else -> throw WrappedIllegalArgumentException("Argument listener ($listener) is invalid for auto.registerEvent")
})
else -> throw WrappedIllegalArgumentException("Argument listener ($listener) is invalid for auto.registerEvent")
})
}
@JvmStatic
@@ -262,6 +267,26 @@ class Auto(private val scriptRuntime: ScriptRuntime) : Augmentable(scriptRuntime
accessibilityTool.clearCache()
}
@JvmStatic
@RhinoRuntimeFunctionInterface
fun currentPackage(scriptRuntime: ScriptRuntime, args: Array<out Any?>): String = ensureArgumentsIsEmpty(args) {
scriptRuntime.info.latestPackage
}
@JvmStatic
@RhinoRuntimeFunctionInterface
fun currentActivity(scriptRuntime: ScriptRuntime, args: Array<out Any?>): String = ensureArgumentsIsEmpty(args) {
scriptRuntime.info.latestActivity
}
@JvmStatic
@RhinoRuntimeFunctionInterface
fun currentComponent(scriptRuntime: ScriptRuntime, args: Array<out Any?>): String = ensureArgumentsIsEmpty(args) {
val latestPackage = scriptRuntime.info.latestPackage.takeUnless { it.isEmpty() } ?: return@ensureArgumentsIsEmpty ""
val latestActivity = scriptRuntime.info.latestActivity.takeUnless { it.isEmpty() } ?: return@ensureArgumentsIsEmpty ""
"$latestPackage/$latestActivity"
}
private fun ensureA11yServiceStarted(scriptRuntime: ScriptRuntime, isForcibleRestart: Any?) {
if (isForcibleRestart !is Boolean) throw WrappedIllegalArgumentException("Argument isForcibleRestart must be of type Boolean")
scriptRuntime.accessibilityBridge.ensureServiceStarted(isForcibleRestart)

View File

@@ -9,18 +9,22 @@ import org.autojs.autojs.extension.AnyExtensions.jsBrief
import org.autojs.autojs.extension.NumberExtensions.string
import org.autojs.autojs.extension.ScriptableExtensions.defineProp
import org.autojs.autojs.extension.ScriptableExtensions.prop
import org.autojs.autojs.extension.ScriptableObjectExtensions.inquire
import org.autojs.autojs.runtime.ScriptRuntime
import org.autojs.autojs.runtime.api.ScreenMetrics
import org.autojs.autojs.runtime.api.augment.Augmentable
import org.autojs.autojs.runtime.api.augment.automator.Auto
import org.autojs.autojs.runtime.api.augment.console.Console
import org.autojs.autojs.runtime.api.augment.jsox.Numberx
import org.autojs.autojs.runtime.api.augment.s13n.S13n
import org.autojs.autojs.runtime.api.augment.selector.Selector
import org.autojs.autojs.runtime.api.augment.shell.Shell
import org.autojs.autojs.runtime.api.augment.shizuku.Shizuku
import org.autojs.autojs.runtime.api.augment.toast.Toast
import org.autojs.autojs.runtime.api.augment.util.Util
import org.autojs.autojs.runtime.exception.WrappedIllegalArgumentException
import org.autojs.autojs.runtime.exception.NotImplementedError
import org.autojs.autojs.runtime.exception.ShouldNeverHappenException
import org.autojs.autojs.runtime.exception.WrappedIllegalArgumentException
import org.autojs.autojs.util.RhinoUtils
import org.autojs.autojs.util.RhinoUtils.NOT_CONSTRUCTABLE
import org.autojs.autojs.util.RhinoUtils.UNDEFINED
@@ -79,6 +83,7 @@ class Global(private val scriptRuntime: ScriptRuntime) : Augmentable(scriptRunti
::getClip.name,
::currentPackage.name,
::currentActivity.name,
::currentComponent.name,
::wait.name,
::waitForActivity.name,
::waitForPackage.name,
@@ -295,14 +300,50 @@ class Global(private val scriptRuntime: ScriptRuntime) : Augmentable(scriptRunti
@JvmStatic
@RhinoRuntimeFunctionInterface
fun currentPackage(scriptRuntime: ScriptRuntime, args: Array<out Any?>): String = ensureArgumentsIsEmpty(args) {
scriptRuntime.info.latestPackage
fun currentPackage(scriptRuntime: ScriptRuntime, args: Array<out Any?>): String = ensureArgumentsAtMost(args, 1) { argList ->
val (o) = argList
when (parseComponentFetchMode(o)) {
ComponentFetchMode.ACCESSIBILITY -> Auto.currentPackage(scriptRuntime, emptyArray())
ComponentFetchMode.SHIZUKU -> Shizuku.currentPackage(scriptRuntime, emptyArray())
ComponentFetchMode.ROOT -> Shell.currentPackage(scriptRuntime, emptyArray())
ComponentFetchMode.AUTOMATISM -> listOf(
{ Shizuku.currentPackage(scriptRuntime, emptyArray()) },
{ Shell.currentPackage(scriptRuntime, emptyArray()) },
{ Auto.currentPackage(scriptRuntime, emptyArray()) }
).firstNotNullOfOrNull { f -> f().takeUnless { it.isEmpty() } }.orEmpty()
}
}
@JvmStatic
@RhinoRuntimeFunctionInterface
fun currentActivity(scriptRuntime: ScriptRuntime, args: Array<out Any?>): String = ensureArgumentsIsEmpty(args) {
scriptRuntime.info.latestActivity
fun currentActivity(scriptRuntime: ScriptRuntime, args: Array<out Any?>): String = ensureArgumentsAtMost(args, 1) { argList ->
val (o) = argList
when (parseComponentFetchMode(o)) {
ComponentFetchMode.ACCESSIBILITY -> Auto.currentActivity(scriptRuntime, emptyArray())
ComponentFetchMode.SHIZUKU -> Shizuku.currentActivity(scriptRuntime, emptyArray())
ComponentFetchMode.ROOT -> Shell.currentActivity(scriptRuntime, emptyArray())
ComponentFetchMode.AUTOMATISM -> listOf(
{ Shizuku.currentActivity(scriptRuntime, emptyArray()) },
{ Shell.currentActivity(scriptRuntime, emptyArray()) },
{ Auto.currentActivity(scriptRuntime, emptyArray()) }
).firstNotNullOfOrNull { f -> f().takeUnless { it.isEmpty() } }.orEmpty()
}
}
@JvmStatic
@RhinoRuntimeFunctionInterface
fun currentComponent(scriptRuntime: ScriptRuntime, args: Array<out Any?>): String = ensureArgumentsAtMost(args, 1) { argList ->
val (o) = argList
when (parseComponentFetchMode(o)) {
ComponentFetchMode.ACCESSIBILITY -> Auto.currentComponent(scriptRuntime, emptyArray())
ComponentFetchMode.SHIZUKU -> Shizuku.currentComponent(scriptRuntime, emptyArray())
ComponentFetchMode.ROOT -> Shell.currentComponent(scriptRuntime, emptyArray())
ComponentFetchMode.AUTOMATISM -> listOf(
{ Shizuku.currentComponent(scriptRuntime, emptyArray()) },
{ Shell.currentComponent(scriptRuntime, emptyArray()) },
{ Auto.currentComponent(scriptRuntime, emptyArray()) }
).firstNotNullOfOrNull { f -> f().takeUnless { it.isEmpty() } }.orEmpty()
}
}
@JvmStatic
@@ -647,6 +688,20 @@ class Global(private val scriptRuntime: ScriptRuntime) : Augmentable(scriptRunti
else -> arrayOf(args.first())
}
private fun parseComponentFetchMode(o: Any?): ComponentFetchMode = when {
o.isJsNullish() -> ComponentFetchMode.AUTOMATISM
o is NativeObject -> parseComponentFetchMode(o.inquire(listOf("by", "mode"), ::coerceString, ""))
else -> when (coerceString(o, "").lowercase()) {
"", "auto", "automatic", "automatism" -> ComponentFetchMode.AUTOMATISM
"a11y", "accessibility" -> ComponentFetchMode.ACCESSIBILITY
"shizuku" -> ComponentFetchMode.SHIZUKU
"root" -> ComponentFetchMode.ROOT
else -> throw WrappedIllegalArgumentException("Unknown component fetch mode: ${coerceString(o)}")
}
}
private enum class ComponentFetchMode { AUTOMATISM, ACCESSIBILITY, SHIZUKU, ROOT }
}
}

View File

@@ -1,5 +1,6 @@
package org.autojs.autojs.runtime.api.augment.shell
import android.util.Log
import android.view.KeyEvent
import androidx.annotation.IntRange
import org.autojs.autojs.annotation.RhinoRuntimeFunctionInterface
@@ -16,6 +17,7 @@ import org.autojs.autojs.util.RhinoUtils.coerceBoolean
import org.autojs.autojs.util.RhinoUtils.coerceIntNumber
import org.autojs.autojs.util.RhinoUtils.coerceString
import org.autojs.autojs.util.RhinoUtils.undefined
import org.autojs.autojs.util.RootUtils
import org.mozilla.javascript.NativeArray
import org.mozilla.javascript.NativeObject
import org.mozilla.javascript.Undefined
@@ -28,6 +30,9 @@ class Shell(private val scriptRuntime: ScriptRuntime) : Augmentable(scriptRuntim
::getCommand.name,
::fromIntent.name,
::kill.name,
::currentPackage.name,
::currentActivity.name,
::currentComponent.name,
)
override val globalAssignmentFunctions = listOf(
@@ -56,6 +61,8 @@ class Shell(private val scriptRuntime: ScriptRuntime) : Augmentable(scriptRuntim
companion object : FlexibleArray() {
private val TAG = Shell::class.java.simpleName
@JvmStatic
@RhinoRuntimeFunctionInterface
fun execCommand(scriptRuntime: ScriptRuntime, args: Array<out Any?>): AbstractShell.Result = ensureArgumentsLengthInRange(args, 1..3) { argList ->
@@ -80,12 +87,56 @@ class Shell(private val scriptRuntime: ScriptRuntime) : Augmentable(scriptRuntim
@JvmStatic
@RhinoRuntimeFunctionInterface
fun kill(scriptRuntime: ScriptRuntime, args: Array<out Any?>): Boolean = ensureArgumentsOnlyOne(args) { app ->
if (!RootUtils.isRootAvailable()) return@ensureArgumentsOnlyOne false
when (val packageName = App.getPackageName(scriptRuntime, arrayOf(app))) {
null -> false
else -> execCommand(scriptRuntime, arrayOf("am force-stop $packageName", true)).code == 0
}
}
@JvmStatic
@RhinoRuntimeFunctionInterface
fun currentPackage(scriptRuntime: ScriptRuntime, args: Array<out Any?>): String = ensureArgumentsIsEmpty(args) {
currentComponent(scriptRuntime, args).substringBefore("/")
}
@JvmStatic
@RhinoRuntimeFunctionInterface
fun currentActivity(scriptRuntime: ScriptRuntime, args: Array<out Any?>): String = ensureArgumentsIsEmpty(args) {
val component = currentComponent(scriptRuntime, args)
val className = component.substringAfterLast("/")
when {
className.startsWith(".") -> component
else -> className
}
}
@JvmStatic
@RhinoRuntimeFunctionInterface
fun currentComponent(scriptRuntime: ScriptRuntime, args: Array<out Any?>): String = ensureArgumentsIsEmpty(args) {
if (!RootUtils.isRootAvailable()) return@ensureArgumentsIsEmpty ""
try {
val process = Runtime.getRuntime().exec("su -c dumpsys activity activities")
process.inputStream.bufferedReader().useLines { lines ->
val resumedActivityLine = lines.find {
it.contains("Resumed:") || it.contains("ResumedActivity")
}
resumedActivityLine?.let { line ->
Log.d(TAG, "Found Resumed Activity: $line")
line.split("\\s+".toRegex()).firstOrNull { part ->
part.contains("/")
}?.let { part ->
Log.d(TAG, "current activity part: $part")
return@ensureArgumentsIsEmpty part.replace("\\W+$".toRegex(), "")
}
}
}
} catch (e: Exception) {
Log.e(TAG, "Error reading current component", e)
}
return@ensureArgumentsIsEmpty ""
}
@JvmStatic
@RhinoRuntimeFunctionInterface
fun Menu(scriptRuntime: ScriptRuntime, args: Array<out Any?>): Undefined = ensureArgumentsIsEmpty(args) {
@@ -323,6 +374,17 @@ class Shell(private val scriptRuntime: ScriptRuntime) : Augmentable(scriptRuntim
.replace(Regex("([a-z])([0-9])"), "$1-$2") // handle letters followed by numbers
.lowercase()
private fun completeActivityNames(name: String): String {
val parts = name.split("/")
if (parts.size == 2) {
val (packageName, activityName) = parts
if (activityName.startsWith(".")) {
return "$packageName/$packageName$activityName"
}
}
return name
}
data class CommandArgumentsData(val arguments: String = "", val withRoot: Boolean = false, val withExit: Boolean = false)
data class CommandData(val command: String, @IntRange(0, 1) val withRoot: Int = 0)

View File

@@ -3,9 +3,11 @@ package org.autojs.autojs.runtime.api.augment.shizuku
import org.autojs.autojs.annotation.RhinoRuntimeFunctionInterface
import org.autojs.autojs.runtime.ScriptRuntime
import org.autojs.autojs.runtime.api.AbstractShell
import org.autojs.autojs.runtime.api.WrappedShizuku
import org.autojs.autojs.runtime.api.augment.Augmentable
import org.autojs.autojs.runtime.api.augment.Invokable
import org.autojs.autojs.runtime.api.augment.shell.Shell.Companion.getCommandData
import org.autojs.autojs.runtime.api.augment.app.App
import org.autojs.autojs.runtime.api.augment.shell.Shell
@Suppress("unused", "UNUSED_PARAMETER")
class Shizuku(private val scriptRuntime: ScriptRuntime) : Augmentable(scriptRuntime), Invokable {
@@ -13,6 +15,10 @@ class Shizuku(private val scriptRuntime: ScriptRuntime) : Augmentable(scriptRunt
override val selfAssignmentFunctions = listOf(
::execCommand.name,
::getCommand.name,
::kill.name,
::currentPackage.name,
::currentActivity.name,
::currentComponent.name,
)
override fun invoke(vararg args: Any?): AbstractShell.Result = execCommand(scriptRuntime, args)
@@ -22,13 +28,50 @@ class Shizuku(private val scriptRuntime: ScriptRuntime) : Augmentable(scriptRunt
@JvmStatic
@RhinoRuntimeFunctionInterface
fun execCommand(scriptRuntime: ScriptRuntime, args: Array<out Any?>): AbstractShell.Result = ensureArgumentsLengthInRange(args, 1..3) { argList ->
scriptRuntime.shizuku.execCommand(getCommandData(argList).command)
scriptRuntime.shizuku.execCommand(Shell.getCommandData(argList).command)
}
@JvmStatic
@RhinoRuntimeFunctionInterface
fun getCommand(scriptRuntime: ScriptRuntime, args: Array<out Any?>): String = ensureArgumentsLengthInRange(args, 1..3) { argList ->
getCommandData(argList).command
Shell.getCommandData(argList).command
}
@JvmStatic
@RhinoRuntimeFunctionInterface
fun kill(scriptRuntime: ScriptRuntime, args: Array<out Any?>): Boolean = ensureArgumentsOnlyOne(args) { app ->
if (!WrappedShizuku.isOperational()) return@ensureArgumentsOnlyOne false
when (val packageName = App.getPackageName(scriptRuntime, arrayOf(app))) {
null -> false
else -> execCommand(scriptRuntime, arrayOf("am force-stop $packageName")).code == 0
}
}
@JvmStatic
@RhinoRuntimeFunctionInterface
fun currentPackage(scriptRuntime: ScriptRuntime, args: Array<out Any?>): String = ensureArgumentsIsEmpty(args) {
when {
!WrappedShizuku.isOperational() -> ""
else -> WrappedShizuku.service?.currentPackage() ?: ""
}
}
@JvmStatic
@RhinoRuntimeFunctionInterface
fun currentActivity(scriptRuntime: ScriptRuntime, args: Array<out Any?>): String = ensureArgumentsIsEmpty(args) {
when {
!WrappedShizuku.isOperational() -> ""
else -> WrappedShizuku.service?.currentActivity() ?: ""
}
}
@JvmStatic
@RhinoRuntimeFunctionInterface
fun currentComponent(scriptRuntime: ScriptRuntime, args: Array<out Any?>): String = ensureArgumentsIsEmpty(args) {
when {
!WrappedShizuku.isOperational() -> ""
else -> WrappedShizuku.service?.currentComponent() ?: ""
}
}
}

View File

@@ -9,7 +9,6 @@ import androidx.preference.Preference.SummaryProvider
import com.afollestad.materialdialogs.MaterialDialog
import org.autojs.autojs.core.pref.Pref
import org.autojs.autojs.ui.common.NotAskAgainDialog
import org.autojs.autojs.util.StringUtils.key
import org.autojs.autojs6.R
open class MaterialListPreference : MaterialDialogPreference {
@@ -43,12 +42,12 @@ open class MaterialListPreference : MaterialDialogPreference {
negativeText = getAttrString(a, R.styleable.MaterialListPreference_negativeText) ?: context.getString(R.string.dialog_button_cancel)
getAttrTextArray(a, R.styleable.MaterialListPreference_itemKeys)?.also { mItemKeys = it.toList() }
getAttrTextArray(a, R.styleable.MaterialListPreference_itemValues)?.also { mItemValues = it.toList() }
bundle.getString(key(R.string.key_pref_bundle_default_item), getAttrString(a, R.styleable.MaterialListPreference_itemDefaultKey))?.also { mItemDefaultKey = it }
bundle.getString(context.getString(R.string.key_pref_bundle_default_item), getAttrString(a, R.styleable.MaterialListPreference_itemDefaultKey))?.also { mItemDefaultKey = it }
getAttrString(a, R.styleable.MaterialListPreference_onConfirmPrompt)?.also { mConfirmedPrompt = it }
a.recycle()
}
bundle.getIntegerArrayList(key(R.string.key_pref_bundle_disabled_items))?.map { context.getString(it) }?.let { disables ->
bundle.getIntegerArrayList(context.getString(R.string.key_pref_bundle_disabled_items))?.map { context.getString(it) }?.let { disables ->
mItemKeys.forEachIndexed { index, it -> if (it in disables) mItemDisables += index }
}

View File

@@ -220,10 +220,12 @@ public class CircularMenuWindow extends FloatyWindow {
}
public void savePosition() {
int x = mActionViewWindowBridge.getX();
Pref.putFloatSync(KEY_POSITION_X_PERCENT, x / (float) ScreenMetrics.getDeviceScreenWidth());
int y = mActionViewWindowBridge.getY();
Pref.putFloatSync(KEY_POSITION_Y_PERCENT, y / (float) ScreenMetrics.getDeviceScreenHeight());
if (mActionViewWindowBridge != null) {
int x = mActionViewWindowBridge.getX();
Pref.putFloatSync(KEY_POSITION_X_PERCENT, x / (float) ScreenMetrics.getDeviceScreenWidth());
int y = mActionViewWindowBridge.getY();
Pref.putFloatSync(KEY_POSITION_Y_PERCENT, y / (float) ScreenMetrics.getDeviceScreenHeight());
}
}
public void savePosition(@NotNull Configuration configuration) {