6.7.0 - Alpha19 - Fine tuning
This commit is contained in:
@@ -98,7 +98,7 @@ open class PointerLocationTool(final override val context: Context) : ShowableIt
|
||||
|
||||
runCatching byShizuku@{
|
||||
when {
|
||||
WrappedShizuku.isOperational() -> {
|
||||
WrappedShizuku.hasService() && WrappedShizuku.isOperational() -> {
|
||||
WrappedShizuku.execCommand(context, cmd).result.trim().toIntOrNull()
|
||||
}
|
||||
else -> null
|
||||
|
||||
@@ -12,7 +12,7 @@ object LooperThread {
|
||||
|
||||
fun getLooperOrNull(thread: Thread) = when {
|
||||
isEqual(thread, Looper.getMainLooper().thread) -> Looper.getMainLooper()
|
||||
thread is ILooperThread -> (thread as ILooperThread).looper
|
||||
thread is ILooperThread -> thread.looper
|
||||
else -> null
|
||||
}
|
||||
|
||||
|
||||
@@ -12,18 +12,19 @@ import org.autojs.autojs.runtime.exception.ScriptInterruptedException
|
||||
import org.mozilla.javascript.BaseFunction
|
||||
import org.mozilla.javascript.Context
|
||||
import java.lang.ref.WeakReference
|
||||
import java.util.*
|
||||
import java.util.WeakHashMap
|
||||
import java.util.concurrent.CountDownLatch
|
||||
|
||||
/**
|
||||
* Created by Stardust on Dec 27, 2017.
|
||||
* Modified by SuperMonster003 as of Jan 31, 2026.
|
||||
*/
|
||||
open class TimerThread(
|
||||
scriptRuntime: ScriptRuntime,
|
||||
private val target: Runnable,
|
||||
) : ThreadCompat(target), ILooperThread {
|
||||
|
||||
private var mRunning = false
|
||||
private val mRunningLock = Object()
|
||||
private val mRunningLatch = CountDownLatch(1)
|
||||
private var mWeakRuntime = WeakReference(scriptRuntime)
|
||||
|
||||
@Volatile
|
||||
@@ -32,54 +33,43 @@ open class TimerThread(
|
||||
@Volatile
|
||||
private var mLooper: Looper? = null
|
||||
|
||||
override val looper: Looper? = mLooper
|
||||
|
||||
var loopers: Loopers? = null
|
||||
|
||||
val timer: Timer
|
||||
get() {
|
||||
checkNotNull(mTimer) { "thread is not alive" }
|
||||
return mTimer as Timer
|
||||
}
|
||||
override val looper: Looper?
|
||||
get() = mLooper
|
||||
|
||||
override fun run() {
|
||||
val scriptRuntime = mWeakRuntime.get() ?: return
|
||||
|
||||
scriptRuntime.loopers.prepare()
|
||||
var timer: Timer
|
||||
mTimer = scriptRuntime.timers.newTimer(scriptRuntime).also { timer = it }
|
||||
sTimerMap[currentThread()] = WeakReference<Timer>(timer)
|
||||
(scriptRuntime.engines.myEngine() as? RhinoJavaScriptEngine)?.enterContext()
|
||||
|
||||
scriptRuntime.timers.newTimer(scriptRuntime).also {
|
||||
mTimer = it
|
||||
sTimerMap[currentThread()] = WeakReference<Timer>(it)
|
||||
}
|
||||
|
||||
val engine = scriptRuntime.engines.myEngine() as? RhinoJavaScriptEngine
|
||||
engine?.enterContext()
|
||||
|
||||
notifyRunning()
|
||||
Looper.myLooper().also { setLooper(it) }
|
||||
?.let { Handler(it).post(target) }
|
||||
try {
|
||||
Looper.loop()
|
||||
onExit()
|
||||
mTimer = null
|
||||
} catch (throwable: Throwable) {
|
||||
try {
|
||||
if (ScriptInterruptedException.causedByInterrupt(throwable)) {
|
||||
return
|
||||
|
||||
val currentLooper = Looper.myLooper()
|
||||
setLooper(currentLooper)
|
||||
currentLooper?.let { Handler(it).post(target) }
|
||||
|
||||
val exceptionHandler: (t: Throwable) -> Unit = { t ->
|
||||
runCatching {
|
||||
if (!ScriptInterruptedException.causedByInterrupt(t)) {
|
||||
val console: Console = mWeakRuntime.get()?.console ?: AutoJs.instance.globalConsole
|
||||
console.error("${currentThread()}: $t")
|
||||
}
|
||||
var console: Console? = null
|
||||
val runtime = mWeakRuntime.get()
|
||||
if (runtime != null) {
|
||||
console = runtime.console
|
||||
}
|
||||
if (console == null) {
|
||||
console = AutoJs.instance.globalConsole
|
||||
}
|
||||
console.error("${Thread.currentThread()}: $throwable")
|
||||
} finally {
|
||||
onExit()
|
||||
mTimer = null
|
||||
Context.exit()
|
||||
sTimerMap.remove(currentThread())
|
||||
}
|
||||
}
|
||||
runCatching { Context.exit() }
|
||||
sTimerMap.remove(currentThread())
|
||||
}
|
||||
|
||||
runCatching { Looper.loop() }.onFailure(exceptionHandler)
|
||||
runCatching { onExit() }.onFailure(exceptionHandler)
|
||||
mTimer = null
|
||||
runCatching { Context.exit() }.onFailure(exceptionHandler)
|
||||
sTimerMap.remove(currentThread())
|
||||
}
|
||||
|
||||
override fun interrupt() {
|
||||
LooperHelper.quit(LooperThread.getLooperOrNull(this))
|
||||
@@ -96,46 +86,58 @@ open class TimerThread(
|
||||
|
||||
@Throws(InterruptedException::class)
|
||||
fun waitFor() {
|
||||
synchronized(mRunningLock) {
|
||||
if (!mRunning) {
|
||||
mRunningLock.wait()
|
||||
}
|
||||
}
|
||||
mRunningLatch.await()
|
||||
}
|
||||
|
||||
fun setTimeout(callback: BaseFunction): Double = setTimeout(callback, 1)
|
||||
fun setTimeout(callback: BaseFunction): Double =
|
||||
setTimeout(callback, 1)
|
||||
|
||||
fun setTimeout(callback: BaseFunction, delay: Long, vararg args: Any): Double = timer.setTimeout(callback, delay, args.copyOf())
|
||||
fun setTimeout(callback: BaseFunction, delay: Long, vararg args: Any): Double = withTimer {
|
||||
setTimeout(callback, delay, args.copyOf())
|
||||
}
|
||||
|
||||
fun clearTimeout(id: Double) = timer.clearTimeout(id)
|
||||
fun clearTimeout(id: Double): Boolean = withTimer {
|
||||
clearTimeout(id)
|
||||
}
|
||||
|
||||
fun setInterval(callback: BaseFunction) = setInterval(callback, 1L)
|
||||
fun setInterval(callback: BaseFunction): Double =
|
||||
setInterval(callback, 1L)
|
||||
|
||||
fun setInterval(callback: BaseFunction, interval: Long, vararg args: Any) = timer.setInterval(callback, interval, args.copyOf())
|
||||
fun setInterval(callback: BaseFunction, interval: Long, vararg args: Any): Double = withTimer {
|
||||
setInterval(callback, interval, args.copyOf())
|
||||
}
|
||||
|
||||
fun clearInterval(id: Double) = timer.clearInterval(id)
|
||||
fun clearInterval(id: Double): Boolean = withTimer {
|
||||
clearInterval(id)
|
||||
}
|
||||
|
||||
fun setImmediate(callback: BaseFunction, vararg args: Any) = timer.setImmediate(callback, args.copyOf())
|
||||
fun setImmediate(callback: BaseFunction, vararg args: Any): Double = withTimer {
|
||||
setImmediate(callback, args.copyOf())
|
||||
}
|
||||
|
||||
fun clearImmediate(id: Double) = timer.clearImmediate(id)
|
||||
fun clearImmediate(id: Double): Boolean = withTimer {
|
||||
clearImmediate(id)
|
||||
}
|
||||
|
||||
private inline fun <R> withTimer(callback: Timer.() -> R): R {
|
||||
val timer = mTimer
|
||||
checkNotNull(timer) { "Thread is not alive" }
|
||||
return callback(timer)
|
||||
}
|
||||
|
||||
private fun setLooper(looper: Looper?) {
|
||||
mLooper = looper
|
||||
}
|
||||
|
||||
private fun notifyRunning() {
|
||||
synchronized(mRunningLock) {
|
||||
mRunning = true
|
||||
mRunningLock.notifyAll()
|
||||
}
|
||||
mRunningLatch.countDown()
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
private val sTimerMap = WeakHashMap<Thread, WeakReference<Timer>>()
|
||||
|
||||
@JvmStatic
|
||||
fun getTimerForThread(thread: Thread) = sTimerMap[thread]?.get()
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1037,10 +1037,9 @@ public class Dim {
|
||||
@Override
|
||||
public void onEngineCreate(ScriptEngine<? extends ScriptSource> engine) {
|
||||
if (type != IPROXY_LISTEN) Kit.codeBug();
|
||||
if (!(engine instanceof RhinoJavaScriptEngine) ||
|
||||
!callback.shouldAttachDebugger((RhinoJavaScriptEngine) engine)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(engine instanceof RhinoJavaScriptEngine)) return;
|
||||
if (!callback.shouldAttachDebugger((RhinoJavaScriptEngine) engine)) return;
|
||||
|
||||
Context cx = ((RhinoJavaScriptEngine) engine).getContext();
|
||||
ContextData contextData = new ContextData();
|
||||
|
||||
@@ -45,7 +45,7 @@ public class Dialogs {
|
||||
MaterialDialog.Builder builder = dialogBuilder(callback)
|
||||
.alert()
|
||||
.title(title)
|
||||
.positiveText(R.string.text_ok);
|
||||
.positiveText(R.string.dialog_button_dismiss);
|
||||
if (!TextUtils.isEmpty(content)) {
|
||||
builder.content(content);
|
||||
}
|
||||
@@ -57,8 +57,8 @@ public class Dialogs {
|
||||
MaterialDialog.Builder builder = dialogBuilder(callback)
|
||||
.confirm()
|
||||
.title(title)
|
||||
.positiveText(R.string.text_ok)
|
||||
.negativeText(R.string.text_cancel);
|
||||
.positiveText(R.string.dialog_button_confirm)
|
||||
.negativeText(R.string.dialog_button_cancel);
|
||||
if (!TextUtils.isEmpty(content)) {
|
||||
builder.content(content);
|
||||
}
|
||||
@@ -86,7 +86,7 @@ public class Dialogs {
|
||||
return ((BlockedMaterialDialog.Builder) dialogBuilder(callback)
|
||||
.itemsCallbackSingleChoice(selectedIndex)
|
||||
.title(title)
|
||||
.positiveText(R.string.text_ok)
|
||||
.positiveText(R.string.dialog_button_confirm)
|
||||
.items(items))
|
||||
.showAndGet();
|
||||
}
|
||||
@@ -96,7 +96,7 @@ public class Dialogs {
|
||||
return ((BlockedMaterialDialog.Builder) dialogBuilder(callback)
|
||||
.itemsCallbackMultiChoice(ArrayUtils.box(indices))
|
||||
.title(title)
|
||||
.positiveText(R.string.text_ok)
|
||||
.positiveText(R.string.dialog_button_confirm)
|
||||
.items(items))
|
||||
.showAndGet();
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ class UI(context: Context, private val scriptRuntime: ScriptRuntime) : ProxyObje
|
||||
it.context = context
|
||||
}
|
||||
|
||||
private val mProperties = ConcurrentHashMap<String, Any?>().also {
|
||||
private val mProperties = ConcurrentHashMap<String, Any>().also {
|
||||
it["layoutInflater"] = layoutInflater
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ object Util {
|
||||
fun getClassName(o: Any?) = getClassNameInternal(o, "getClassName")
|
||||
|
||||
private fun getClassInternal(o: Any?, methodName: String): Class<out Any> {
|
||||
require(o != null) { "Argument \"o\" ${o.jsBrief()} for util.$methodName must be non-null" }
|
||||
requireNotNull(o) { "Argument \"o\" ${o.jsBrief()} for util.$methodName must be non-null" }
|
||||
return o as? Class<*> ?: o.javaClass
|
||||
}
|
||||
|
||||
|
||||
@@ -139,7 +139,7 @@ object WrappedShizuku {
|
||||
}
|
||||
|
||||
@ScriptInterface
|
||||
fun isOperational() = hasService() && isRunning() && hasPermission()
|
||||
fun isOperational() = isRunning() && hasPermission()
|
||||
|
||||
@ScriptInterface
|
||||
fun isRunning() = mHasBinder
|
||||
@@ -147,6 +147,15 @@ object WrappedShizuku {
|
||||
@ScriptInterface
|
||||
fun hasService() = service != null
|
||||
|
||||
@JvmStatic
|
||||
fun getServiceOrNull(): IUserService? {
|
||||
service?.let { return it }
|
||||
bindUserServiceIfNeeded()
|
||||
initializeShizukuServiceAndWait(5000L)
|
||||
service?.let { return it }
|
||||
return null
|
||||
}
|
||||
|
||||
@ScriptInterface
|
||||
fun requestPermission() = Shizuku.requestPermission(mRequestCode)
|
||||
|
||||
|
||||
@@ -266,7 +266,7 @@ abstract class Augmentable(private val scriptRuntime: ScriptRuntime? = null) : A
|
||||
}
|
||||
|
||||
if (this is AsEmitter) {
|
||||
require(scriptRuntime != null) { "Augmentable instance of AsEmitter must have a non-null scriptRuntime property" }
|
||||
requireNotNull(scriptRuntime) { "Augmentable instance of AsEmitter must have a non-null scriptRuntime property" }
|
||||
objProtoList += Events.__asEmitter__(scriptRuntime, emptyArray())
|
||||
}
|
||||
|
||||
|
||||
@@ -1170,7 +1170,7 @@ class Images(scriptRuntime: ScriptRuntime) : Augmentable(scriptRuntime), AsEmitt
|
||||
var bitmap: Bitmap? = null
|
||||
try {
|
||||
image = read(scriptRuntime, argList)
|
||||
require(image != null) { "Image path ${argList[0]} is invalid for images.readPixels" }
|
||||
requireNotNull(image) { "Image path ${argList[0]} is invalid for images.readPixels" }
|
||||
bitmap = image.bitmap
|
||||
val w = bitmap.width
|
||||
val h = bitmap.height
|
||||
|
||||
@@ -81,7 +81,7 @@ internal fun extendBuildInObjectInternal(scriptRuntime: ScriptRuntime, augmentab
|
||||
}
|
||||
protoList.forEach { pair ->
|
||||
val (funcName, attributes) = pair
|
||||
require(extensibleProtoClass != null) { "A proto class must be specified for build-in object prototype extension" }
|
||||
requireNotNull(extensibleProtoClass) { "A proto class must be specified for build-in object prototype extension" }
|
||||
|
||||
val prototypeObject = buildInObject.prop("prototype") as ScriptableObject
|
||||
|
||||
|
||||
@@ -3,9 +3,14 @@ package org.autojs.autojs.runtime.api.augment.shell
|
||||
import android.util.Log
|
||||
import android.view.KeyEvent
|
||||
import org.autojs.autojs.annotation.RhinoRuntimeFunctionInterface
|
||||
import org.autojs.autojs.rhino.ArgumentGuards
|
||||
import org.autojs.autojs.rhino.ArgumentGuards.Companion.component1
|
||||
import org.autojs.autojs.rhino.ArgumentGuards.Companion.component2
|
||||
import org.autojs.autojs.rhino.ArgumentGuards.Companion.component3
|
||||
import org.autojs.autojs.rhino.ArgumentGuards.Companion.component4
|
||||
import org.autojs.autojs.rhino.ArgumentGuards.Companion.component5
|
||||
import org.autojs.autojs.rhino.extension.AnyExtensions.isJsNullish
|
||||
import org.autojs.autojs.rhino.extension.AnyExtensions.jsBrief
|
||||
import org.autojs.autojs.rhino.ArgumentGuards
|
||||
import org.autojs.autojs.runtime.ScriptRuntime
|
||||
import org.autojs.autojs.runtime.api.AbstractShell
|
||||
import org.autojs.autojs.runtime.api.augment.Augmentable
|
||||
@@ -132,16 +137,17 @@ class Shell(private val scriptRuntime: ScriptRuntime) : Augmentable(scriptRuntim
|
||||
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 part.replace("\\W+$".toRegex(), "")
|
||||
}
|
||||
}
|
||||
} ?: return@useLines
|
||||
|
||||
Log.d(TAG, "Found Resumed Activity: $resumedActivityLine")
|
||||
|
||||
val activityPart = resumedActivityLine.split("\\s+".toRegex()).firstOrNull { part ->
|
||||
part.contains("/")
|
||||
} ?: return@useLines
|
||||
|
||||
Log.d(TAG, "current activity part: $activityPart")
|
||||
|
||||
return activityPart.replace("\\W+$".toRegex(), "")
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Error reading current component", e)
|
||||
|
||||
@@ -28,6 +28,7 @@ class Shizuku(private val scriptRuntime: ScriptRuntime) : Augmentable(scriptRunt
|
||||
"state" to Supplier {
|
||||
newNativeObject().also { o ->
|
||||
o.defineProp("isInstalled", WrappedShizuku.isInstalled(globalContext))
|
||||
o.defineProp("hasService", WrappedShizuku.hasService())
|
||||
o.defineProp("isRunning", WrappedShizuku.isRunning())
|
||||
o.defineProp("hasPermission", WrappedShizuku.hasPermission())
|
||||
o.defineProp("isOperational", WrappedShizuku.isOperational())
|
||||
|
||||
@@ -24,6 +24,7 @@ import org.autojs.autojs.core.pref.Language;
|
||||
import org.autojs.autojs.core.pref.Pref;
|
||||
import org.autojs.autojs.core.record.GlobalActionRecorder;
|
||||
import org.autojs.autojs.core.record.Recorder;
|
||||
import org.autojs.autojs.core.shizuku.IUserService;
|
||||
import org.autojs.autojs.model.explorer.ExplorerDirPage;
|
||||
import org.autojs.autojs.model.explorer.ExplorerPage;
|
||||
import org.autojs.autojs.model.explorer.Explorers;
|
||||
@@ -414,9 +415,12 @@ public class CircularMenu implements LayoutInspector.CaptureAvailableListener {
|
||||
private String getCurrentPackage() {
|
||||
if (WrappedShizuku.INSTANCE.isOperational()) {
|
||||
try {
|
||||
mCurrentPackage = Objects.requireNonNull(WrappedShizuku.service).currentPackage();
|
||||
if (!TextUtils.isEmpty(mCurrentPackage)) {
|
||||
return mCurrentPackage;
|
||||
IUserService service = WrappedShizuku.getServiceOrNull();
|
||||
if (service != null) {
|
||||
mCurrentPackage = service.currentPackage();
|
||||
if (!TextUtils.isEmpty(mCurrentPackage)) {
|
||||
return mCurrentPackage;
|
||||
}
|
||||
}
|
||||
} catch (RemoteException ignored) {
|
||||
/* Ignored. */
|
||||
@@ -439,9 +443,12 @@ public class CircularMenu implements LayoutInspector.CaptureAvailableListener {
|
||||
private String getCurrentActivity() {
|
||||
if (WrappedShizuku.INSTANCE.isOperational()) {
|
||||
try {
|
||||
mCurrentActivity = Objects.requireNonNull(WrappedShizuku.service).currentActivity();
|
||||
if (!TextUtils.isEmpty(mCurrentActivity)) {
|
||||
return mCurrentActivity;
|
||||
IUserService service = WrappedShizuku.getServiceOrNull();
|
||||
if (service != null) {
|
||||
mCurrentActivity = service.currentActivity();
|
||||
if (!TextUtils.isEmpty(mCurrentActivity)) {
|
||||
return mCurrentActivity;
|
||||
}
|
||||
}
|
||||
} catch (RemoteException ignored) {
|
||||
/* Ignored. */
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#Sat Jan 31 15:04:03 CST 2026
|
||||
BUILD_TIME=1769843043403
|
||||
#Sat Jan 31 18:47:47 CST 2026
|
||||
BUILD_TIME=1769856467115
|
||||
COMPILE_SDK_VERSION=36
|
||||
IMAGE_QUANT_CMAKE_VERSION=3.22.1
|
||||
IMAGE_QUANT_NDK_VERSION=26.1.10909125
|
||||
@@ -27,6 +27,6 @@ RAPID_OCR_OPENCV_MOBILE_LABEL_VERSION=13
|
||||
RAPID_OCR_OPENCV_MOBILE_VERSION=4.5.3
|
||||
TARGET_SDK_VERSION=36
|
||||
TARGET_SDK_VERSION_INRT=29
|
||||
VERSION_BUILD=3678
|
||||
VERSION_BUILD=3679
|
||||
VERSION_NAME=6.7.0 Alpha19
|
||||
VSCODE_EXT_REQUIRED_VERSION=1.0.13
|
||||
|
||||
Reference in New Issue
Block a user