6.6.1 - Alpha2 - 优化 app.startActivity/startDualActivity 等方法适配性

This commit is contained in:
SuperMonster003
2024-12-27 19:42:12 +08:00
parent 13b71a4310
commit cfb8557545
35 changed files with 333 additions and 197 deletions

View File

@@ -18,11 +18,13 @@ import org.autojs.autojs.runtime.api.AppUtils.Companion.BroadcastShortForm
import org.autojs.autojs.runtime.api.WrappedShizuku
import org.autojs.autojs.runtime.api.augment.Augmentable
import org.autojs.autojs.runtime.api.augment.shell.Shell
import org.autojs.autojs.runtime.exception.WrappedIllegalArgumentException
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.UNDEFINED
import org.autojs.autojs.util.RhinoUtils.coerceBoolean
import org.autojs.autojs.util.RhinoUtils.coerceString
import org.autojs.autojs.util.RhinoUtils.js_object_assign
import org.autojs.autojs.util.RhinoUtils.newNativeArray
import org.autojs.autojs.util.RhinoUtils.newNativeObject
import org.autojs.autojs.util.RhinoUtils.undefined
@@ -56,6 +58,7 @@ class App(scriptRuntime: ScriptRuntime) : Augmentable(scriptRuntime) {
::sendLocalBroadcastSync.name,
::parseUri.name,
::openUrl.name,
::openDualUrl.name,
::getUriForFile.name,
::getAppByAlias.name,
::launch.name to AS_GLOBAL,
@@ -98,131 +101,117 @@ class App(scriptRuntime: ScriptRuntime) : Augmentable(scriptRuntime) {
@JvmStatic
@RhinoFunctionBody
fun intentRhinoWithRuntime(scriptRuntime: ScriptRuntime, o: Any?): Intent {
if (o is Intent) return o
require(o is NativeObject) {
"Argument for app.intent must be a JavaScript Object rather than ${o?.javaClass?.name ?: "null"}"
}
val intent = Intent()
if (!o.prop("url").isJsNullish()) {
o.put("data", o, parseIntentUrl(scriptRuntime, o))
}
if (!o.prop("package").isJsNullish()) {
if (o.prop("packageName").isJsNullish()) {
o.put("packageName", o, o.prop("package"))
}
} else {
if (!o.prop("packageName").isJsNullish()) {
o.put("package", o, o.prop("packageName"))
}
}
if (!o.prop("packageName").isJsNullish()) {
val k = Context.toString(o.prop("packageName"))
if (k in presetPackageNames) {
o.defineProp("packageName", presetPackageNames[k])
}
if (!o.prop("className").isJsNullish()) {
intent.setClassName(coerceString(o.prop("packageName")), parseClassName(o))
} else {
// @Hint by SuperMonster003 on Jun 23, 2020.
// ! the Intent can only match the components
// ! in the given application package with setPackage().
// ! Otherwise, if there's more than one app that can handle the intent,
// ! the system presents the user with a dialog to pick which app to use.
// ! zh-CN:
// ! Intent 只能匹配通过 setPackage() 设置的给定应用包中的组件.
// ! 否则, 如果有多个应用可以处理该 Intent,
// ! 系统会向用户展示一个对话框, 让用户选择要使用哪个应用.
intent.setPackage(coerceString(o.prop("packageName")))
}
}
if (o.prop("extras") is NativeObject) {
(o.prop("extras") as NativeObject).entries.forEach { entry ->
val (key, value) = entry
RhinoUtils.putExtraForIntent(intent, key, value)
}
}
if (!o.prop("category").isJsNullish()) {
if (o.prop("category") is Iterable<*>) {
(o.prop("category") as Iterable<*>).forEach { cat ->
intent.addCategory(Context.toString(cat))
}
} else {
intent.addCategory(Context.toString(o.prop("category")))
}
}
if (!o.prop("action").isJsNullish()) {
intent.setAction(parseIntentAction(o.prop("action")))
}
if (!o.prop("flags").isJsNullish()) {
intent.setFlags(parseIntentFlags(o.prop("flags")))
}
if (!o.prop("type").isJsNullish()) {
if (!o.prop("data").isJsNullish()) {
intent.setDataAndType(parseUriRhinoWithRuntime(scriptRuntime, o.prop("data")), Context.toString(o.prop("type")))
} else {
intent.setType(Context.toString(o.prop("type")))
}
} else {
if (!o.prop("data").isJsNullish()) {
intent.setData(Uri.parse(Context.toString(o.prop("data"))))
}
}
return intent
fun intentRhinoWithRuntime(scriptRuntime: ScriptRuntime, o: Any?): Intent = when (o) {
is Intent -> o
is NativeObject -> Intent().configure(scriptRuntime, o)
else -> throw IllegalArgumentException("Argument for app.intent must be either an Intent or a JavaScript Object rather than ${o.jsBrief()}")
}
@JvmStatic
@RhinoRuntimeFunctionInterface
fun startActivity(scriptRuntime: ScriptRuntime, args: Array<out Any?>): Unit = ensureArgumentsOnlyOne(args) { o ->
when (o) {
@Suppress("HttpUrlsUsage")
fun startActivity(scriptRuntime: ScriptRuntime, args: Array<out Any?>): Undefined = ensureArgumentsLengthInRange(args, 1..2) { argList ->
val (obj, options) = argList
when (obj) {
is String -> when {
o.contains("://") -> {
openUrlRhino(o)
}
rexWebSiteWithoutProtocol.matches(o) -> {
@Suppress("HttpUrlsUsage")
openUrlRhino("http://$o")
}
!options.isJsNullish() -> throw IllegalArgumentException("Method app.startActivity can only have one argument when argument[0] is String")
obj.contains("://") -> openUrlRhino(obj)
rexWebSiteWithoutProtocol.matches(obj) -> openUrlRhino("http://$obj")
else -> runCatching {
startActivityWithGlobalContext(Intent(globalContext, ActivityShortForm.valueOf(o.uppercase()).classType))
startActivityWithGlobalContext(Intent(globalContext, ActivityShortForm.valueOf(obj.uppercase()).classType))
}.getOrElse {
when (it) {
is WrappedIllegalArgumentException -> throw WrappedIllegalArgumentException("Activity short form $o cannot be found")
is WrappedIllegalArgumentException -> throw WrappedIllegalArgumentException("Activity short form $obj cannot be found")
else -> throw it
}
}
}
is Intent -> when {
WrappedShizuku.isOperational() -> WrappedShizuku.execCommand("am start ${toIntentToShell(scriptRuntime, o)}")
else -> startActivityWithGlobalContext(o)
options.isJsNullish() -> startActivityWithGlobalContext(obj)
options is NativeObject -> obj.configure(scriptRuntime, options).let { configuredIntent ->
when {
checkDualProperty(options) -> startDualActivity(scriptRuntime, args)
checkRootProperty(options) && RootUtils.isRootAvailable() -> {
val tmpIntent = configuredIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
Shell.execCommand(scriptRuntime, arrayOf("am start ${intentToShellRhino(tmpIntent)}", /* withRoot = */ true)).throwIfError()
}
checkShizukuProperty(options) && WrappedShizuku.isOperational() -> {
val tmpIntent = configuredIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
WrappedShizuku.execCommand("am start ${intentToShellRhino(tmpIntent)}").throwIfError()
}
else -> startActivityWithGlobalContext(configuredIntent)
}
}
else -> throw IllegalArgumentException("Argument[1] for app.startActivity must be a JavaScript Object when argument[0] is Intent")
}
is URI -> openUrlRhino(o)
is NativeObject -> when {
checkDualProperty(o) -> startDualActivity(scriptRuntime, args)
checkRootProperty(o) -> Shell.execCommand(scriptRuntime, arrayOf("am start ${toIntentToShell(scriptRuntime, o)}", true)).throwIfError()
WrappedShizuku.isOperational() -> WrappedShizuku.execCommand("am start ${toIntentToShell(scriptRuntime, o)}").throwIfError()
else -> startActivityWithGlobalContext(scriptRuntime, o)
is URI -> when {
!options.isJsNullish() -> throw IllegalArgumentException("Method app.startActivity can only have one argument when argument[0] is URI")
else -> openUrlRhino(obj)
}
else -> startActivityWithGlobalContext(scriptRuntime, o)
is NativeObject -> {
val opt = when {
options.isJsNullish() -> obj
options is NativeObject -> js_object_assign(js_object_assign(newNativeObject(), obj), options) as NativeObject
else -> throw IllegalArgumentException("Argument[1] for app.startActivity must be a JavaScript Object when argument[0] is JavaScript Object")
}
when {
checkDualProperty(opt) -> startDualActivity(scriptRuntime, args)
checkRootProperty(opt) && RootUtils.isRootAvailable() -> {
val tmpIntent = intentRhinoWithRuntime(scriptRuntime, opt).apply { addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) }
Shell.execCommand(scriptRuntime, arrayOf("am start ${intentToShellRhino(tmpIntent)}", /* withRoot = */ true)).throwIfError()
}
checkShizukuProperty(opt) && WrappedShizuku.isOperational() -> {
val tmpIntent = intentRhinoWithRuntime(scriptRuntime, opt).apply { addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) }
val intentCommand = intentToShellRhino(tmpIntent)
WrappedShizuku.execCommand("am start $intentCommand").throwIfError()
}
else -> startActivityWithGlobalContext(scriptRuntime, opt)
}
}
else -> throw IllegalArgumentException("Unknown type of argument[0]: ${obj.jsBrief()}; method: app.startActivity")
}
UNDEFINED
}
@JvmStatic
@RhinoRuntimeFunctionInterface
fun startDualActivity(scriptRuntime: ScriptRuntime, args: Array<out Any?>): Unit = ensureArgumentsOnlyOne(args) { intent ->
execCommandByDualUser(scriptRuntime, intent)
@Suppress("HttpUrlsUsage")
fun startDualActivity(scriptRuntime: ScriptRuntime, args: Array<out Any?>): Undefined = ensureArgumentsLengthInRange(args, 1..2) { argList ->
val (obj, options) = argList
when (obj) {
is String -> when {
!options.isJsNullish() -> throw IllegalArgumentException("Method app.startDualActivity can only have one argument when argument[0] is String")
obj.contains("://") -> openDualUrlRhino(scriptRuntime, obj)
rexWebSiteWithoutProtocol.matches(obj) -> openDualUrlRhino(scriptRuntime, "http://$obj")
else -> runCatching {
startActivityForDualUser(scriptRuntime, Intent(globalContext, ActivityShortForm.valueOf(obj.uppercase()).classType))
}.getOrElse {
when (it) {
is WrappedIllegalArgumentException -> throw WrappedIllegalArgumentException("Activity short form $obj cannot be found")
else -> throw it
}
}
}
is Intent -> when {
options.isJsNullish() -> startActivityForDualUser(scriptRuntime, obj)
options is NativeObject -> startActivityForDualUser(scriptRuntime, obj.configure(scriptRuntime, options))
else -> throw IllegalArgumentException("Argument[1] for app.startDualActivity must be a JavaScript Object when argument[0] is Intent")
}
is URI -> when {
!options.isJsNullish() -> throw IllegalArgumentException("Method app.startDualActivity can only have one argument when argument[0] is URI")
else -> openUrlRhino(obj)
}
is NativeObject -> {
val opt = when {
options.isJsNullish() -> obj
options is NativeObject -> js_object_assign(js_object_assign(newNativeObject(), obj), options) as NativeObject
else -> throw IllegalArgumentException("Argument[1] for app.startDualActivity must be a JavaScript Object when argument[0] is JavaScript Object")
}
startActivityForDualUser(scriptRuntime, opt)
}
else -> throw IllegalArgumentException("Unknown type of argument[0]: ${obj.jsBrief()}; method: app.startDualActivity")
}
UNDEFINED
}
@JvmStatic
@@ -383,19 +372,20 @@ class App(scriptRuntime: ScriptRuntime) : Augmentable(scriptRuntime) {
@JvmStatic
@RhinoRuntimeFunctionInterface
fun startService(scriptRuntime: ScriptRuntime, args: Array<out Any?>): Unit = ensureArgumentsOnlyOne(args) { o ->
fun startService(scriptRuntime: ScriptRuntime, args: Array<out Any?>): Undefined = ensureArgumentsOnlyOne(args) { o ->
when {
o is NativeObject && checkRootProperty(o) -> {
@Suppress("SpellCheckingInspection")
Shell.execCommand(scriptRuntime, arrayOf(/* cmd = */ "am startservice ${intentToShellRhino(o)}", /* withRoot = */ 1))
Shell.execCommand(scriptRuntime, arrayOf(/* cmd = */ "am startservice ${intentToShellRhino(o)}", /* withRoot = */ true))
}
else -> globalContext.startService(intentRhinoWithRuntime(scriptRuntime, o))
}
UNDEFINED
}
@JvmStatic
@RhinoRuntimeFunctionInterface
fun sendEmail(scriptRuntime: ScriptRuntime, args: Array<out Any?>): Unit = ensureArgumentsOnlyOne(args) { options ->
fun sendEmail(scriptRuntime: ScriptRuntime, args: Array<out Any?>): Undefined = ensureArgumentsOnlyOne(args) { options ->
val optionsMap = options as? NativeObject ?: newNativeObject()
val emailIntent = Intent(Intent.ACTION_SEND).apply {
@@ -422,11 +412,13 @@ class App(scriptRuntime: ScriptRuntime) : Augmentable(scriptRuntime) {
}
startActivityWithGlobalContext(Intent.createChooser(emailIntent, "Send Email"))
UNDEFINED
}
@JvmStatic
@RhinoRuntimeFunctionInterface
fun sendBroadcast(scriptRuntime: ScriptRuntime, args: Array<out Any?>): Unit = ensureArgumentsOnlyOne(args) { o ->
fun sendBroadcast(scriptRuntime: ScriptRuntime, args: Array<out Any?>): Undefined = ensureArgumentsOnlyOne(args) { o ->
when (o) {
is String -> {
runCatching {
@@ -443,11 +435,12 @@ class App(scriptRuntime: ScriptRuntime) : Augmentable(scriptRuntime) {
}
else -> when {
o is NativeObject && checkRootProperty(o) -> {
Shell.execCommand(scriptRuntime, arrayOf("am broadcast ${intentToShellRhino(o)}", 1))
Shell.execCommand(scriptRuntime, arrayOf("am broadcast ${intentToShellRhino(o)}", /* withRoot = */ true))
}
else -> globalContext.sendBroadcast(intentRhinoWithRuntime(scriptRuntime, o))
}
}
UNDEFINED
}
@JvmStatic
@@ -490,10 +483,20 @@ class App(scriptRuntime: ScriptRuntime) : Augmentable(scriptRuntime) {
openUrlRhino(it)
}
@JvmStatic
@RhinoRuntimeFunctionInterface
fun openDualUrl(scriptRuntime: ScriptRuntime, args: Array<out Any?>): Undefined = ensureArgumentsOnlyOne(args) {
openDualUrlRhino(scriptRuntime, it)
}
@JvmStatic
@RhinoFunctionBody
fun openUrlRhino(url: Any?) = undefined { openUrlInternal(coerceString(url)) }
@JvmStatic
@RhinoFunctionBody
fun openDualUrlRhino(scriptRuntime: ScriptRuntime, url: Any?) = undefined { openDualUrlInternal(scriptRuntime, coerceString(url)) }
@Suppress("HttpUrlsUsage")
fun openUrlInternal(url: String) {
val prefix = "http://".takeUnless { url.contains("://") } ?: ""
@@ -503,6 +506,15 @@ class App(scriptRuntime: ScriptRuntime) : Augmentable(scriptRuntime) {
.let { globalContext.startActivity(it) }
}
@Suppress("HttpUrlsUsage")
private fun openDualUrlInternal(scriptRuntime: ScriptRuntime, url: String) {
val prefix = "http://".takeUnless { url.contains("://") } ?: ""
Intent(Intent.ACTION_VIEW)
.setData(Uri.parse(prefix + url))
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
.let { startActivityForDualUser(scriptRuntime, it) }
}
@JvmStatic
@RhinoRuntimeFunctionInterface
fun getUriForFile(scriptRuntime: ScriptRuntime, args: Array<out Any?>): Uri? = ensureArgumentsOnlyOne(args) { o ->
@@ -559,7 +571,7 @@ class App(scriptRuntime: ScriptRuntime) : Augmentable(scriptRuntime) {
o is PresetApp -> launchDualPackageInternal(scriptRuntime, o.packageName)
else -> launchDualPackageInternal(scriptRuntime, getAppByAliasRhino(o)?.packageName ?: Context.toString(o))
}
}.isSuccess
}.getOrElse { false }
}
@JvmStatic
@@ -588,7 +600,7 @@ class App(scriptRuntime: ScriptRuntime) : Augmentable(scriptRuntime) {
launchDualPackageInternal(scriptRuntime, it.packageName)
} ?: launchDualAppInternal(scriptRuntime, Context.toString(o))
}
}.isSuccess
}.getOrElse { false }
}
@JvmStatic
@@ -656,7 +668,7 @@ class App(scriptRuntime: ScriptRuntime) : Augmentable(scriptRuntime) {
@JvmStatic
@RhinoRuntimeFunctionInterface
fun uninstall(scriptRuntime: ScriptRuntime, args: Array<out Any?>): Unit = ensureArgumentsOnlyOne(args) { o ->
fun uninstall(scriptRuntime: ScriptRuntime, args: Array<out Any?>): Undefined = ensureArgumentsOnlyOne(args) { o ->
when {
o.isJsNullish() -> Unit
o is PresetApp -> scriptRuntime.app.uninstall(o.packageName)
@@ -664,11 +676,12 @@ class App(scriptRuntime: ScriptRuntime) : Augmentable(scriptRuntime) {
scriptRuntime.app.uninstall(it.packageName)
} ?: scriptRuntime.app.uninstall(Context.toString(o))
}
UNDEFINED
}
@JvmStatic
@RhinoRuntimeFunctionInterface
fun uninstallDual(scriptRuntime: ScriptRuntime, args: Array<out Any?>): Unit = ensureArgumentsOnlyOne(args) { o ->
fun uninstallDual(scriptRuntime: ScriptRuntime, args: Array<out Any?>): Undefined = ensureArgumentsOnlyOne(args) { o ->
when {
o.isJsNullish() -> Unit
o is PresetApp -> uninstallDualInternal(scriptRuntime, o.packageName)
@@ -676,6 +689,7 @@ class App(scriptRuntime: ScriptRuntime) : Augmentable(scriptRuntime) {
uninstallDualInternal(scriptRuntime, it.packageName)
} ?: uninstallDualInternal(scriptRuntime, Context.toString(o))
}
UNDEFINED
}
// TODO by SuperMonster003 on May 23, 2024.
@@ -728,10 +742,10 @@ class App(scriptRuntime: ScriptRuntime) : Augmentable(scriptRuntime) {
val packageName = getPackageName(scriptRuntime, argList) ?: return@ensureArgumentsLength false
val command = "am force-stop $packageName"
when {
RootUtils.isRootAvailable() -> Shell.execCommand(scriptRuntime, arrayOf(command, true)).code == 0
WrappedShizuku.isOperational() -> WrappedShizuku.execCommand(command).code == 0
else -> Shell.execCommand(scriptRuntime, arrayOf(command, false)).code == 0
}
RootUtils.isRootAvailable() -> Shell.execCommand(scriptRuntime, arrayOf(command, /* withRoot = */ true))
WrappedShizuku.isOperational() -> WrappedShizuku.execCommand(command)
else -> Shell.execCommand(scriptRuntime, arrayOf(command, /* withRoot = */ false))
}.code == 0
}
// @Hint by SuperMonster003 on Oct 30, 2024.
@@ -743,7 +757,7 @@ class App(scriptRuntime: ScriptRuntime) : Augmentable(scriptRuntime) {
fun killDual(scriptRuntime: ScriptRuntime, args: Array<out Any?>): Boolean = ensureArgumentsLength(args, 1) { argList ->
val packageName = getPackageName(scriptRuntime, argList) ?: return@ensureArgumentsLength false
val command = "am force-stop $packageName"
runCatching { execCommandByDualUser(scriptRuntime, command, RootUtils.isRootAvailable()) }.isSuccess
runCatching { execCommandForDualUser(scriptRuntime, command, RootUtils.isRootAvailable(), WrappedShizuku.isOperational()) }.isSuccess
}
private fun parseClassName(o: NativeObject): String {
@@ -761,11 +775,18 @@ class App(scriptRuntime: ScriptRuntime) : Augmentable(scriptRuntime) {
private fun parseIntentFlags(flags: Any?): Int {
fun parse(o: Any?) =
fun parse(o: Any?): Int =
when (o) {
is String -> Intent::class.java.fields
.firstOrNull { it.name == "FLAG_${o.uppercase()}" }
?.getInt(null)
is String -> {
if (o.contains("|")) {
o.split(Regex("\\s*\\|\\s*")).map(::parse).fold(0) { a, b -> a or b }
} else {
Intent::class.java.fields.firstOrNull {
val sanitizedInputRegex = Regex.escape(o.replace(Regex("\\W"), "_"))
it.name.matches(Regex("(flag_)?(activity_)?$sanitizedInputRegex(_task)?", RegexOption.IGNORE_CASE))
}?.getInt(null)
}
}
is Number -> o.toInt()
else -> null
} ?: throw WrappedIllegalArgumentException("Invalid flags: $o")
@@ -830,21 +851,20 @@ class App(scriptRuntime: ScriptRuntime) : Augmentable(scriptRuntime) {
globalContext.startActivity(o.apply { addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) })
}
private fun toIntentToShell(scriptRuntime: ScriptRuntime, intent: Any?) = intentToShellRhino(intentRhinoWithRuntime(scriptRuntime, intent))
private fun execCommandByDualUser(scriptRuntime: ScriptRuntime, intent: Any?) {
executeCommandForDualUser(scriptRuntime, { userIdentifier ->
"am start ${toIntentToShell(scriptRuntime, intent)} --user $userIdentifier"
}, intent is NativeObject && checkRootProperty(intent))
private fun startActivityForDualUser(scriptRuntime: ScriptRuntime, o: Any?) {
val intent = intentRhinoWithRuntime(scriptRuntime, o).apply { addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) }
val command = "am start ${intentToShellRhino(intent)}"
when (o) {
is NativeObject -> {
val withRoot = o.inquire("root", ::coerceBoolean, true)
val withShizuku = o.inquire("shizuku", ::coerceBoolean, true)
execCommandForDualUser(scriptRuntime, command, withRoot, withShizuku)
}
else -> execCommandForDualUser(scriptRuntime, command)
}
}
private fun execCommandByDualUser(scriptRuntime: ScriptRuntime, command: String, withRoot: Boolean) {
executeCommandForDualUser(scriptRuntime, { userIdentifier ->
"$command --user $userIdentifier"
}, withRoot)
}
private fun executeCommandForDualUser(scriptRuntime: ScriptRuntime, commandSupplier: (Int) -> String, withRoot: Boolean) {
private fun execCommandForDualUser(scriptRuntime: ScriptRuntime, command: String, withRoot: Boolean = true, withShizuku: Boolean = true) {
val userManager = globalContext.getSystemService(Class.forName("android.os.UserManager"))
val getUserProfilesMethod = userManager.javaClass.getDeclaredMethod("getUserProfiles")
@@ -861,11 +881,11 @@ class App(scriptRuntime: ScriptRuntime) : Augmentable(scriptRuntime) {
for (userHandle in userProfiles) {
val currentUserIdentifier = getIdentifierMethod.invoke(userHandle) as Int
if (currentUserIdentifier != processUserIdentifier) {
val command = commandSupplier(currentUserIdentifier)
val niceCommand = "$command --user $currentUserIdentifier"
when {
withRoot -> Shell.execCommand(scriptRuntime, arrayOf(command, 1))
WrappedShizuku.isOperational() -> WrappedShizuku.execCommand(command)
else -> Shell.execCommand(scriptRuntime, arrayOf(command, 0))
withRoot && RootUtils.isRootAvailable() -> Shell.execCommand(scriptRuntime, arrayOf(niceCommand, /* withRoot = */ true))
withShizuku && WrappedShizuku.isOperational() -> WrappedShizuku.execCommand(niceCommand)
else -> Shell.execCommand(scriptRuntime, arrayOf(niceCommand, /* withRoot = */ false))
}.throwIfError()
}
}
@@ -875,32 +895,113 @@ class App(scriptRuntime: ScriptRuntime) : Augmentable(scriptRuntime) {
return o?.let { PresetApp.getAppByAlias(Context.toString(it)) }
}
private fun launchDualPackageInternal(scriptRuntime: ScriptRuntime, o: String) {
private fun launchDualPackageInternal(scriptRuntime: ScriptRuntime, o: String): Boolean {
val nicePackageName = getAppByAlias(scriptRuntime, arrayOf(o))?.packageName ?: (/* packageName = */ o)
val intent = globalContext.packageManager.getLaunchIntentForPackage(nicePackageName) ?: return
execCommandByDualUser(scriptRuntime, intent)
val intent = globalContext.packageManager.getLaunchIntentForPackage(nicePackageName) ?: return false
startActivityForDualUser(scriptRuntime, intent)
return true
}
private fun launchDualAppInternal(scriptRuntime: ScriptRuntime, packageName: String) {
getPackageName(scriptRuntime, arrayOf(packageName))?.let { launchDualPackageInternal(scriptRuntime, it) } ?: false
private fun launchDualAppInternal(scriptRuntime: ScriptRuntime, packageName: String): Boolean {
return getPackageName(scriptRuntime, arrayOf(packageName))?.let { launchDualPackageInternal(scriptRuntime, it) } ?: false
}
private fun launchDualSettingsInternal(scriptRuntime: ScriptRuntime, packageName: String) {
execCommandByDualUser(scriptRuntime, Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply {
addCategory(Intent.CATEGORY_DEFAULT)
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
startActivityForDualUser(scriptRuntime, Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply {
data = Uri.parse("package:$packageName")
})
}
private fun uninstallDualInternal(scriptRuntime: ScriptRuntime, packageName: String) {
execCommandByDualUser(scriptRuntime, Intent(Intent.ACTION_DELETE, Uri.parse("package:$packageName")))
startActivityForDualUser(scriptRuntime, Intent(Intent.ACTION_DELETE).apply {
data = Uri.parse("package:$packageName")
})
}
private fun checkRootProperty(o: NativeObject) = o.inquire("root", ::coerceBoolean, false)
private fun checkShizukuProperty(o: NativeObject) = o.inquire("shizuku", ::coerceBoolean, false) && WrappedShizuku.isOperational()
private fun checkDualProperty(o: NativeObject) = o.inquire("dual", ::coerceBoolean, false)
private fun Intent.configure(scriptRuntime: ScriptRuntime, o: NativeObject): Intent {
val intent = this
if (!o.prop("url").isJsNullish()) {
o.put("data", o, parseIntentUrl(scriptRuntime, o))
}
if (!o.prop("package").isJsNullish()) {
if (o.prop("packageName").isJsNullish()) {
o.put("packageName", o, o.prop("package"))
}
} else {
if (!o.prop("packageName").isJsNullish()) {
o.put("package", o, o.prop("packageName"))
}
}
if (!o.prop("packageName").isJsNullish()) {
val k = Context.toString(o.prop("packageName"))
if (k in presetPackageNames) {
o.defineProp("packageName", presetPackageNames[k])
}
if (!o.prop("className").isJsNullish()) {
intent.setClassName(coerceString(o.prop("packageName")), parseClassName(o))
} else {
// @Hint by SuperMonster003 on Jun 23, 2020.
// ! the Intent can only match the components
// ! in the given application package with setPackage().
// ! Otherwise, if there's more than one app that can handle the intent,
// ! the system presents the user with a dialog to pick which app to use.
// ! zh-CN:
// ! Intent 只能匹配通过 setPackage() 设置的给定应用包中的组件.
// ! 否则, 如果有多个应用可以处理该 Intent,
// ! 系统会向用户展示一个对话框, 让用户选择要使用哪个应用.
intent.setPackage(coerceString(o.prop("packageName")))
}
}
if (o.prop("extras") is NativeObject) {
(o.prop("extras") as NativeObject).entries.forEach { entry ->
val (key, value) = entry
RhinoUtils.putExtraForIntent(intent, key, value)
}
}
if (!o.prop("category").isJsNullish()) {
if (o.prop("category") is Iterable<*>) {
(o.prop("category") as Iterable<*>).forEach { cat ->
intent.addCategory(Context.toString(cat))
}
} else {
intent.addCategory(Context.toString(o.prop("category")))
}
}
if (!o.prop("action").isJsNullish()) {
intent.setAction(parseIntentAction(o.prop("action")))
}
if (!o.prop("flags").isJsNullish()) {
intent.setFlags(parseIntentFlags(o.prop("flags")))
}
if (!o.prop("type").isJsNullish()) {
if (!o.prop("data").isJsNullish()) {
intent.setDataAndType(parseUriRhinoWithRuntime(scriptRuntime, o.prop("data")), Context.toString(o.prop("type")))
} else {
intent.setType(Context.toString(o.prop("type")))
}
} else {
if (!o.prop("data").isJsNullish()) {
intent.setData(Uri.parse(Context.toString(o.prop("data"))))
}
}
return intent
}
}
}

View File

@@ -7,11 +7,13 @@ import org.autojs.autojs.extension.FlexibleArray
import org.autojs.autojs.runtime.ScriptRuntime
import org.autojs.autojs.runtime.api.augment.Augmentable
import org.autojs.autojs.runtime.exception.ShouldNeverHappenException
import org.autojs.autojs.util.RhinoUtils.UNDEFINED
import org.autojs.autojs.util.RhinoUtils.coerceFunction
import org.autojs.autojs.util.RhinoUtils.coerceLongNumber
import org.autojs.autojs.util.RhinoUtils.coerceNumber
import org.autojs.autojs6.R
import org.mozilla.javascript.BaseFunction
import org.mozilla.javascript.Undefined
@Suppress("unused", "UNUSED_PARAMETER")
open class Timers(scriptRuntime: ScriptRuntime) : Augmentable(scriptRuntime) {
@@ -89,10 +91,11 @@ open class Timers(scriptRuntime: ScriptRuntime) : Augmentable(scriptRuntime) {
@JvmStatic
@RhinoRuntimeFunctionInterface
fun loop(scriptRuntime: ScriptRuntime, args: Array<out Any?>): Unit = ensureArgumentsIsEmpty(args) {
fun loop(scriptRuntime: ScriptRuntime, args: Array<out Any?>): Undefined = ensureArgumentsIsEmpty(args) {
AutoJs.instance.globalConsole.warn("")
AutoJs.instance.globalConsole.warn(AutoJs.instance.applicationContext.getString(R.string.error_abandoned_method, "loop"))
AutoJs.instance.globalConsole.warn("")
UNDEFINED
}
@JvmStatic