From 330ae87f4c3fa907dde98628f3364d7b946486c5 Mon Sep 17 00:00:00 2001
From: Ai <132525856+LZX284@users.noreply.github.com>
Date: Sat, 30 Sep 2023 13:51:10 +0800
Subject: [PATCH] =?UTF-8?q?=E5=90=88=E5=B9=B6=E6=89=93=E5=8C=85=E5=8A=9F?=
=?UTF-8?q?=E8=83=BD=E4=BB=A3=E7=A0=81?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
autoJS打包目前只能兼容V1版本的签名,而由于谷歌的限制,如果targetSdk为30或以上的话,打包的应用就无法安装,所以打包(构建时选择inrt分支)时需要将TARGET_SDK_VERSION设置为29或以下。
---
app/build.gradle.kts | 57 ++-
app/src/main/AndroidManifest.xml | 360 +++++++++---------
.../java/org/autojs/autojs/AbstractAutoJs.kt | 24 +-
app/src/main/java/org/autojs/autojs/AutoJs.kt | 2 +-
.../main/java/org/autojs/autojs/inrt/App.kt | 86 +++++
.../org/autojs/autojs/inrt/LogActivity.kt | 51 +++
.../main/java/org/autojs/autojs/inrt/Pref.kt | 50 +++
.../autojs/autojs/inrt/SettingsActivity.kt | 38 ++
.../org/autojs/autojs/inrt/SplashActivity.kt | 89 +++++
.../org/autojs/autojs/inrt/autojs/AutoJs.kt | 98 +++++
.../autojs/inrt/autojs/GlobalKeyObserver.kt | 93 +++++
.../autojs/ScriptExecutionGlobalListener.kt | 36 ++
.../autojs/inrt/autojs/XJavaScriptEngine.kt | 44 +++
.../inrt/launch/AssetsProjectLauncher.kt | 110 ++++++
.../inrt/launch/GlobalProjectLauncher.kt | 10 +
.../org/autojs/autojs/inrt/launch/MD5.java | 31 ++
.../main/res/layout/activity_main_inrt.xml | 30 ++
.../res/layout/activity_settings_inrt.xml | 29 ++
.../main/res/layout/activity_splash_inrt.xml | 22 ++
app/src/main/res/menu/menu_main_inrt.xml | 7 +
app/src/main/res/values/attrs.xml | 8 +
app/src/main/res/xml/preference_inrt.xml | 45 +++
app/src/main/res/xml/provider_paths.xml | 3 +-
23 files changed, 1141 insertions(+), 182 deletions(-)
create mode 100644 app/src/main/java/org/autojs/autojs/inrt/App.kt
create mode 100644 app/src/main/java/org/autojs/autojs/inrt/LogActivity.kt
create mode 100644 app/src/main/java/org/autojs/autojs/inrt/Pref.kt
create mode 100644 app/src/main/java/org/autojs/autojs/inrt/SettingsActivity.kt
create mode 100644 app/src/main/java/org/autojs/autojs/inrt/SplashActivity.kt
create mode 100644 app/src/main/java/org/autojs/autojs/inrt/autojs/AutoJs.kt
create mode 100644 app/src/main/java/org/autojs/autojs/inrt/autojs/GlobalKeyObserver.kt
create mode 100644 app/src/main/java/org/autojs/autojs/inrt/autojs/ScriptExecutionGlobalListener.kt
create mode 100644 app/src/main/java/org/autojs/autojs/inrt/autojs/XJavaScriptEngine.kt
create mode 100644 app/src/main/java/org/autojs/autojs/inrt/launch/AssetsProjectLauncher.kt
create mode 100644 app/src/main/java/org/autojs/autojs/inrt/launch/GlobalProjectLauncher.kt
create mode 100644 app/src/main/java/org/autojs/autojs/inrt/launch/MD5.java
create mode 100644 app/src/main/res/layout/activity_main_inrt.xml
create mode 100644 app/src/main/res/layout/activity_settings_inrt.xml
create mode 100644 app/src/main/res/layout/activity_splash_inrt.xml
create mode 100644 app/src/main/res/menu/menu_main_inrt.xml
create mode 100644 app/src/main/res/xml/preference_inrt.xml
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index 1411ca8d..5f6e6dc8 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -288,6 +288,45 @@ android {
minSdk = versions.sdkVersionMin
targetSdk = versions.sdkVersionTarget
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
+ buildConfigField("boolean", "isInrt", "false")
+ }
+
+ flavorDimensions.add("channel")
+ productFlavors {
+ create("app") {
+ dimension = "channel"
+ versionCode = versions.appVersionCode
+ versionName = versions.appVersionName
+ buildConfigField("String", "CHANNEL", "\"app\"")
+ buildConfigField("boolean", "isInrt", "false")
+ manifestPlaceholders.putAll(
+ mapOf(
+ "CHANNEL" to "app",
+ "appName" to "@string/app_name",
+ "intentCategory" to "android.intent.category.LAUNCHER",
+ "intentCategoryInrt" to "android.intent.category.DEFAULT",
+ "authorities" to "org.autojs.autojs6.fileprovider"
+ )
+ )
+ }
+
+ create("inrt") {
+ dimension = "channel"
+ applicationIdSuffix = ".inrt"
+ versionCode = versions.appVersionCode
+ versionName = versions.appVersionName
+ buildConfigField("String", "CHANNEL", "\"inrt\"")
+ buildConfigField("boolean", "isInrt", "true")
+ manifestPlaceholders.putAll(
+ mapOf(
+ "CHANNEL" to "inrt",
+ "appName" to "AutoJs6.inrt",
+ "intentCategory" to "android.intent.category.DEFAULT",
+ "intentCategoryInrt" to "android.intent.category.LAUNCHER",
+ "authorities" to "org.autojs.autojs6.inrt.fileprovider"
+ )
+ )
+ }
}
compileOptions {
@@ -312,6 +351,9 @@ android {
"META-INF/ASL2.0",
"META-INF/*.kotlin_module",
).let { resources.pickFirsts.addAll(it) }
+ jniLibs {
+ useLegacyPackaging = true
+ }
}
kotlinOptions {
@@ -369,13 +411,22 @@ android {
javaCompileOptions {
annotationProcessorOptions {
mapOf(
- "resourcePackageName" to (this@defaultConfig.applicationId ?: this@Build_gradle.applicationId),
+ "resourcePackageName" to (this@defaultConfig.applicationId
+ ?: this@Build_gradle.applicationId),
"androidManifestFile" to ("$projectDir/src/main/AndroidManifest.xml")
).let { arguments(it) }
}
}
- buildConfigField("String", "VERSION_DATE", "\"${Utils.getDateString("MMM d, yyyy", "GMT+08:00")}\"")
- buildConfigField("String", "VSCODE_EXT_REQUIRED_VERSION", "\"${versions.vscodeExtRequiredVersion}\"")
+ buildConfigField(
+ "String",
+ "VERSION_DATE",
+ "\"${Utils.getDateString("MMM d, yyyy", "GMT+08:00")}\""
+ )
+ buildConfigField(
+ "String",
+ "VSCODE_EXT_REQUIRED_VERSION",
+ "\"${versions.vscodeExtRequiredVersion}\""
+ )
}
applicationVariants.all {
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 8523e9c6..60658c6f 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -1,9 +1,9 @@
+ xmlns:tools="http://schemas.android.com/tools">
+ android:required="false"/>
-
+
-
+
-
+
+ tools:ignore="ProtectedPermissions"/>
+ tools:ignore="QueryAllPackagesPermission"/>
+ tools:ignore="ProtectedPermissions"/>
+ tools:ignore="ProtectedPermissions"/>
+ tools:ignore="ProtectedPermissions"/>
-
+
-
+
-
+
-
+
-
+
+ android:name="CHANNEL"
+ android:value="${CHANNEL}"/>
-
-
-
-
+
+
@@ -150,148 +149,138 @@
android:name="org.autojs.autojs.ui.main.MainActivity"
android:exported="true"
android:launchMode="singleTask"
- android:theme="@style/AppTheme.FullScreen" />
+ android:theme="@style/AppTheme.FullScreen"/>
+ android:theme="@android:style/Theme.NoDisplay">
-
+
-
+
-
-
-
-
+ android:theme="@style/EditorTheme"/>
+ android:theme="@style/AppTheme.Settings"/>
+ android:theme="@style/AppTheme.Settings"/>
+ android:theme="@style/AppTheme.Settings"/>
-
+
+ android:configChanges="orientation|keyboardHidden|screenSize|locale"/>
+ android:configChanges="orientation|keyboardHidden|screenSize|locale"/>
-
+
-
+
+ android:theme="@style/AppTheme.FullScreen">
-
+
-
+
-
+
-
+
+ android:theme="@style/AppTheme.Transparent"/>
-
+
-
+
-
+
-
+
-
+
-
+
-
+
+ android:permission="android.permission.BIND_QUICK_SETTINGS_TILE">
+ android:value="true"/>
-
+
+ android:permission="android.permission.BIND_QUICK_SETTINGS_TILE">
+ android:value="true"/>
-
+
@@ -305,7 +294,7 @@
tools:ignore="ExportedActivity">
-
+
@@ -316,71 +305,71 @@
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
+ tools:ignore="BatteryLife"/>
-
+
-
+
-
+
-
+
-
+
-
+
@@ -395,99 +384,99 @@
-
+
+ android:label="@string/text_edit_script">
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
+ android:theme="@android:style/Theme.NoDisplay">
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
+ android:theme="@style/AppTheme.Transparent">
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
+ android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">
-
+
@@ -496,12 +485,12 @@
android:exported="false">
-
+
+ android:resource="@xml/script_widget_config"/>
@@ -509,7 +498,7 @@
android:name="org.autojs.autojs.timing.TaskReceiver"
android:exported="false">
-
+
@@ -525,44 +514,44 @@
+ android:theme="@style/MtAppTheme.FullScreen"/>
+ android:theme="@style/ScriptTheme"/>
+ android:theme="@style/ScriptTheme.Transparent"/>
+ android:theme="@style/ScriptTheme.Transparent"/>
+ android:exported="true"
+ android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
-
+
+ android:resource="@xml/accessibility_service_config"/>
+ android:foregroundServiceType="mediaProjection"/>
+ android:permission="android.permission.INTERACT_ACROSS_USERS_FULL"/>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/java/org/autojs/autojs/AbstractAutoJs.kt b/app/src/main/java/org/autojs/autojs/AbstractAutoJs.kt
index eb2992d5..c44f0599 100644
--- a/app/src/main/java/org/autojs/autojs/AbstractAutoJs.kt
+++ b/app/src/main/java/org/autojs/autojs/AbstractAutoJs.kt
@@ -20,6 +20,7 @@ import org.autojs.autojs.engine.RootAutomatorEngine
import org.autojs.autojs.engine.ScriptEngineManager
import org.autojs.autojs.engine.ScriptEngineService
import org.autojs.autojs.engine.ScriptEngineServiceBuilder
+import org.autojs.autojs.inrt.autojs.XJavaScriptEngine
import org.autojs.autojs.pref.Pref.registerOnSharedPreferenceChangeListener
import org.autojs.autojs.rhino.InterruptibleAndroidContextFactory
import org.autojs.autojs.runtime.ScriptRuntime
@@ -58,9 +59,17 @@ abstract class AbstractAutoJs protected constructor(protected val application: A
val infoProvider = ActivityInfoProvider(context)
val scriptEngineManager = ScriptEngineManager(context)
val scriptEngineService: ScriptEngineService = run {
- scriptEngineManager.registerEngine(JavaScriptSource.ENGINE) {
- LoopBasedJavaScriptEngine(context).also { engine ->
- engine.runtime = createRuntime().also { runtime = it }
+ if (org.autojs.autojs6.BuildConfig.isInrt) {
+ scriptEngineManager.registerEngine(JavaScriptSource.ENGINE) {
+ XJavaScriptEngine(context).also { engine ->
+ engine.runtime = createRuntime().also { runtime = it }
+ }
+ }
+ } else {
+ scriptEngineManager.registerEngine(JavaScriptSource.ENGINE) {
+ LoopBasedJavaScriptEngine(context).also { engine ->
+ engine.runtime = createRuntime().also { runtime = it }
+ }
}
}
initContextFactory()
@@ -84,7 +93,14 @@ abstract class AbstractAutoJs protected constructor(protected val application: A
}
private fun initContextFactory() {
- ContextFactory.initGlobal(InterruptibleAndroidContextFactory(File(context.cacheDir, "classes")))
+ ContextFactory.initGlobal(
+ InterruptibleAndroidContextFactory(
+ File(
+ context.cacheDir,
+ "classes"
+ )
+ )
+ )
}
protected open fun createRuntime(): ScriptRuntime = ScriptRuntime.Builder()
diff --git a/app/src/main/java/org/autojs/autojs/AutoJs.kt b/app/src/main/java/org/autojs/autojs/AutoJs.kt
index 88c9cedd..cbeeea10 100644
--- a/app/src/main/java/org/autojs/autojs/AutoJs.kt
+++ b/app/src/main/java/org/autojs/autojs/AutoJs.kt
@@ -38,7 +38,7 @@ import java.util.concurrent.Executors
* Modified by SuperMonster003 as of Dec 1, 2021.
* Transformed by SuperMonster003 on Oct 10, 2022.
*/
-class AutoJs private constructor(private val appContext: Application) : AbstractAutoJs(appContext) {
+open class AutoJs(private val appContext: Application) : AbstractAutoJs(appContext) {
// @Thank to Zen2H
private val printExecutor = Executors.newSingleThreadExecutor()
diff --git a/app/src/main/java/org/autojs/autojs/inrt/App.kt b/app/src/main/java/org/autojs/autojs/inrt/App.kt
new file mode 100644
index 00000000..f504699f
--- /dev/null
+++ b/app/src/main/java/org/autojs/autojs/inrt/App.kt
@@ -0,0 +1,86 @@
+package org.autojs.autojs.inrt
+
+import android.app.Application
+import android.graphics.Bitmap
+import android.graphics.drawable.Drawable
+import android.net.Uri
+import android.view.View
+import android.widget.ImageView
+
+import com.bumptech.glide.Glide
+import com.bumptech.glide.request.target.SimpleTarget
+import com.bumptech.glide.request.transition.Transition
+import org.autojs.autojs.inrt.App
+import org.autojs.autojs.AutoJs
+import org.autojs.autojs.inrt.autojs.GlobalKeyObserver
+import org.autojs.autojs.app.GlobalAppContext
+import org.autojs.autojs.core.ui.inflater.ImageLoader
+import org.autojs.autojs.core.ui.inflater.util.Drawables
+import java.lang.ref.WeakReference
+
+/**
+ * Created by Stardust on 2017/7/1.
+ */
+class App : Application() {
+ companion object {
+
+ private const val BUGLY_APP_ID = "19b3607b53"
+
+ private lateinit var instance: WeakReference
+
+ val app: App
+ get() = instance.get()!!
+
+ }
+
+ override fun onCreate() {
+ super.onCreate()
+ GlobalAppContext.set(this)
+ instance = WeakReference(this)
+ AutoJs.initInstance(this)
+ GlobalKeyObserver.init()
+ Drawables.defaultImageLoader=object : ImageLoader {
+ override fun loadInto(imageView: ImageView, uri: Uri) {
+ Glide.with(this@App)
+ .load(uri)
+ .into(imageView)
+ }
+
+ override fun loadIntoBackground(view: View, uri: Uri) {
+ Glide.with(this@App)
+ .load(uri)
+ .into(object : SimpleTarget() {
+ override fun onResourceReady(resource: Drawable, transition: Transition?) {
+ view.background = resource
+ }
+ })
+ }
+
+ override fun load(view: View, uri: Uri): Drawable {
+ throw UnsupportedOperationException()
+ }
+
+ override fun load(view: View, uri: Uri, drawableCallback: ImageLoader.DrawableCallback) {
+ Glide.with(this@App)
+ .load(uri)
+ .into(object : SimpleTarget() {
+ override fun onResourceReady(resource: Drawable, transition: Transition?) {
+ drawableCallback.onLoaded(resource)
+ }
+ })
+ }
+
+ override fun load(view: View, uri: Uri, bitmapCallback: ImageLoader.BitmapCallback) {
+ Glide.with(this@App)
+ .asBitmap()
+ .load(uri)
+ .into(object : SimpleTarget() {
+ override fun onResourceReady(resource: Bitmap, transition: Transition?) {
+ bitmapCallback.onLoaded(resource)
+ }
+ })
+ }
+ }
+ }
+
+}
diff --git a/app/src/main/java/org/autojs/autojs/inrt/LogActivity.kt b/app/src/main/java/org/autojs/autojs/inrt/LogActivity.kt
new file mode 100644
index 00000000..6786b216
--- /dev/null
+++ b/app/src/main/java/org/autojs/autojs/inrt/LogActivity.kt
@@ -0,0 +1,51 @@
+package org.autojs.autojs.inrt
+
+import android.content.Intent
+import android.os.Bundle
+import androidx.appcompat.app.AppCompatActivity
+import androidx.appcompat.widget.Toolbar
+import android.view.Menu
+import android.view.MenuItem
+import android.view.View
+
+import org.autojs.autojs.AutoJs
+import org.autojs.autojs.inrt.launch.GlobalProjectLauncher
+import org.autojs.autojs.core.console.ConsoleImpl
+import org.autojs.autojs.core.console.ConsoleView
+import org.autojs.autojs6.R
+
+class LogActivity : AppCompatActivity() {
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setupView()
+ if (intent.getBooleanExtra(EXTRA_LAUNCH_SCRIPT, false)) {
+ GlobalProjectLauncher.launch(this)
+ }
+ }
+
+ private fun setupView() {
+ setContentView(R.layout.activity_main_inrt)
+ val toolbar = findViewById(R.id.toolbar)
+ setSupportActionBar(toolbar)
+ val consoleView = findViewById(R.id.console)
+ consoleView.setConsole(AutoJs.instance.globalConsole as ConsoleImpl)
+ consoleView.findViewById(R.id.input_container).visibility = View.GONE
+ }
+
+ override fun onOptionsItemSelected(item: MenuItem): Boolean {
+ startActivity(Intent(this, SettingsActivity::class.java))
+ return true
+ }
+
+ override fun onCreateOptionsMenu(menu: Menu): Boolean {
+ menuInflater.inflate(R.menu.menu_main_inrt, menu)
+ return true
+ }
+
+ companion object {
+
+
+ const val EXTRA_LAUNCH_SCRIPT = "launch_script"
+ }
+}
diff --git a/app/src/main/java/org/autojs/autojs/inrt/Pref.kt b/app/src/main/java/org/autojs/autojs/inrt/Pref.kt
new file mode 100644
index 00000000..8152e754
--- /dev/null
+++ b/app/src/main/java/org/autojs/autojs/inrt/Pref.kt
@@ -0,0 +1,50 @@
+package org.autojs.autojs.inrt
+
+import android.content.SharedPreferences
+import androidx.preference.PreferenceManager
+
+import org.autojs.autojs.app.GlobalAppContext
+import org.autojs.autojs6.R
+
+/**
+ * Created by Stardust on 2017/12/8.
+ */
+object Pref {
+
+ private const val KEY_FIRST_USING = "key_first_using"
+ private var sPreferences: SharedPreferences? = null
+
+ private val preferences: SharedPreferences
+ get() {
+ return sPreferences ?: run {
+ val pref = PreferenceManager.getDefaultSharedPreferences(GlobalAppContext.get())
+ sPreferences = pref
+ pref
+ }
+ }
+
+ val isFirstUsing: Boolean
+ get() {
+ val firstUsing = preferences.getBoolean(KEY_FIRST_USING, true)
+ if (firstUsing) {
+ preferences.edit().putBoolean(KEY_FIRST_USING, false).apply()
+ }
+ return firstUsing
+ }
+
+ private fun getString(res: Int): String {
+ return GlobalAppContext.get().getString(res)
+ }
+
+ fun shouldEnableAccessibilityServiceByRoot(): Boolean {
+ return preferences.getBoolean(getString(R.string.key_enable_a11y_service_with_root_access), true)
+ }
+
+ fun shouldHideLogs(): Boolean {
+ return preferences.getBoolean(getString(R.string.key_not_showing_main_activity), false)
+ }
+
+ fun shouldStopAllScriptsWhenVolumeUp(): Boolean {
+ return preferences.getBoolean(getString(R.string.key_use_volume_control_running), true)
+ }
+}
diff --git a/app/src/main/java/org/autojs/autojs/inrt/SettingsActivity.kt b/app/src/main/java/org/autojs/autojs/inrt/SettingsActivity.kt
new file mode 100644
index 00000000..44899e85
--- /dev/null
+++ b/app/src/main/java/org/autojs/autojs/inrt/SettingsActivity.kt
@@ -0,0 +1,38 @@
+package org.autojs.autojs.inrt
+
+import android.os.Bundle
+import androidx.annotation.Nullable
+import androidx.appcompat.app.AppCompatActivity
+import androidx.appcompat.widget.Toolbar
+import org.autojs.autojs6.R
+
+/**
+ * Created by Stardust on 2017/12/8.
+ */
+class SettingsActivity : AppCompatActivity() {
+ override fun onCreate(@Nullable savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setupViews()
+ }
+
+ private fun setupViews() {
+ setContentView(R.layout.activity_settings_inrt)
+ fragmentManager.beginTransaction().replace(R.id.fragment_setting, PreferenceFragment()).commit()
+ val toolbar = findViewById(R.id.toolbar)
+ toolbar.setTitle(R.string.text_settings)
+ setSupportActionBar(toolbar)
+ toolbar.setNavigationOnClickListener { finish() }
+ supportActionBar?.setDisplayHomeAsUpEnabled(true)
+ }
+
+ class PreferenceFragment : androidx.preference.PreferenceFragment() {
+
+ override fun onCreate(@Nullable savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ }
+
+ override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
+ addPreferencesFromResource(R.xml.preference_inrt)
+ }
+ }
+}
diff --git a/app/src/main/java/org/autojs/autojs/inrt/SplashActivity.kt b/app/src/main/java/org/autojs/autojs/inrt/SplashActivity.kt
new file mode 100644
index 00000000..b760e121
--- /dev/null
+++ b/app/src/main/java/org/autojs/autojs/inrt/SplashActivity.kt
@@ -0,0 +1,89 @@
+package org.autojs.autojs.inrt
+
+import android.Manifest
+import android.content.Intent
+import android.content.pm.PackageManager.PERMISSION_DENIED
+import android.graphics.Typeface
+import android.os.Bundle
+import android.os.Handler
+import android.os.Looper
+import android.widget.TextView
+import android.widget.Toast
+import androidx.annotation.NonNull
+import androidx.annotation.Nullable
+import androidx.appcompat.app.AppCompatActivity
+import org.autojs.autojs.AutoJs
+import org.autojs.autojs.inrt.launch.GlobalProjectLauncher
+import org.autojs.autojs6.R
+
+/**
+ * Created by Stardust on 2018/2/2.
+ */
+class SplashActivity : AppCompatActivity() {
+
+ override fun onCreate(@Nullable savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.activity_splash_inrt)
+ val slug = findViewById(R.id.slug)
+ slug.typeface = Typeface.createFromAsset(assets, "roboto_medium.ttf")
+ if (!Pref.isFirstUsing) {
+ main()
+ } else {
+ Handler(Looper.myLooper()!!).postDelayed({ this@SplashActivity.main() }, INIT_TIMEOUT)
+ }
+ }
+
+ private fun main() {
+ checkPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE,
+ Manifest.permission.READ_PHONE_STATE)
+ }
+
+
+ private fun runScript() {
+ Thread {
+ try {
+ GlobalProjectLauncher.launch(this)
+ } catch (e: Exception) {
+ e.printStackTrace()
+ runOnUiThread {
+ Toast.makeText(this@SplashActivity, e.message, Toast.LENGTH_LONG).show()
+ startActivity(Intent(this@SplashActivity, LogActivity::class.java))
+ AutoJs.instance.globalConsole.printAllStackTrace(e)
+ }
+ }
+ }.start()
+ }
+
+ override fun onRequestPermissionsResult(requestCode: Int, @NonNull permissions: Array, @NonNull grantResults: IntArray) {
+ super.onRequestPermissionsResult(requestCode, permissions, grantResults)
+ runScript()
+ }
+
+ private fun checkPermission(vararg permissions: String) {
+ val requestPermissions = getRequestPermissions(permissions)
+ if (requestPermissions.isNotEmpty()) {
+ requestPermissions(requestPermissions, PERMISSION_REQUEST_CODE)
+ } else {
+ runScript()
+ }
+ }
+
+
+ private fun getRequestPermissions(permissions: Array): Array {
+ val list = ArrayList()
+ for (permission in permissions) {
+ if (checkSelfPermission(permission) == PERMISSION_DENIED) {
+ list.add(permission)
+ }
+ }
+ return list.toTypedArray()
+ }
+
+ companion object {
+
+ private const val PERMISSION_REQUEST_CODE = 11186
+ private const val INIT_TIMEOUT: Long = 1000
+ }
+
+}
+
diff --git a/app/src/main/java/org/autojs/autojs/inrt/autojs/AutoJs.kt b/app/src/main/java/org/autojs/autojs/inrt/autojs/AutoJs.kt
new file mode 100644
index 00000000..a835fb6c
--- /dev/null
+++ b/app/src/main/java/org/autojs/autojs/inrt/autojs/AutoJs.kt
@@ -0,0 +1,98 @@
+package org.autojs.autojs.inrt.autojs
+
+import android.annotation.SuppressLint
+import android.app.Application
+import android.content.Context
+import org.autojs.autojs.app.GlobalAppContext
+import org.autojs.autojs.inrt.LogActivity
+import org.autojs.autojs.inrt.SettingsActivity
+import org.autojs.autojs.core.accessibility.AccessibilityTool
+import org.autojs.autojs.core.accessibility.AccessibilityService
+import org.autojs.autojs.runtime.ScriptRuntime
+import org.autojs.autojs.runtime.api.AppUtils
+import org.autojs.autojs.runtime.exception.ScriptException
+import org.autojs.autojs.runtime.exception.ScriptInterruptedException
+import org.autojs.autojs.script.JavaScriptSource
+import org.autojs.autojs6.R
+
+
+/**
+ * Created by Stardust on 2017/4/2.
+ */
+class AutoJs private constructor(application: Application) : org.autojs.autojs.AutoJs(application) {
+
+ init {
+ scriptEngineService.registerGlobalScriptExecutionListener(ScriptExecutionGlobalListener())
+ scriptEngineManager.registerEngine(JavaScriptSource.ENGINE) {
+ val engine = XJavaScriptEngine(application)
+ engine.runtime = createRuntime()
+ engine
+ }
+ }
+
+ override fun createAppUtils(context: Context): AppUtils {
+ return AppUtils(context, context.packageName + ".fileprovider")
+ }
+
+ override fun ensureAccessibilityServiceEnabled() {
+ if (AccessibilityService.instance != null) {
+ return
+ }
+ var errorMessage: String? = null
+ if (isAccessibilityServiceEnabled()) {
+ errorMessage = GlobalAppContext.get().getString(R.string.text_a11y_service_enabled_but_not_running)
+ } else if (!getAccessibilityServiceTool().service.enableIfNeededAndWaitFor(2000)) {
+ errorMessage = GlobalAppContext.get().getString(R.string.error_no_accessibility_permission)
+ }
+ if (errorMessage != null) {
+ getAccessibilityServiceTool().launchSettings()
+ throw ScriptException(errorMessage)
+ }
+ }
+
+ override fun waitForAccessibilityServiceEnabled(timeout: Long) {
+ if (AccessibilityService.instance != null) {
+ return
+ }
+ var errorMessage: String? = null
+ if (isAccessibilityServiceEnabled()) {
+ errorMessage = GlobalAppContext.get().getString(R.string.text_a11y_service_enabled_but_not_running)
+ } else if (!getAccessibilityServiceTool().service.enableIfNeededAndWaitFor(2000)) {
+ errorMessage = GlobalAppContext.get().getString(R.string.error_no_accessibility_permission)
+ }
+ if (errorMessage != null) {
+ getAccessibilityServiceTool().launchSettings()
+ if (!AccessibilityService.waitForEnabled(timeout)) {
+ throw ScriptInterruptedException()
+ }
+ }
+ }
+
+ override fun createRuntime(): ScriptRuntime {
+ val runtime = super.createRuntime()
+ runtime.putProperty("class.settings", SettingsActivity::class.java)
+ runtime.putProperty("class.console", LogActivity::class.java)
+ return runtime
+ }
+
+ private fun getAccessibilityServiceTool(): AccessibilityTool {
+ return AccessibilityTool(application)
+ }
+
+ private fun isAccessibilityServiceEnabled(): Boolean {
+ return getAccessibilityServiceTool().service.isEnabled()
+ }
+
+ companion object {
+
+ @SuppressLint("StaticFieldLeak")
+ @JvmStatic
+ lateinit var instance: AutoJs
+ private set
+
+ @Synchronized
+ fun initInstance(application: Application) {
+ instance = AutoJs(application)
+ }
+ }
+}
diff --git a/app/src/main/java/org/autojs/autojs/inrt/autojs/GlobalKeyObserver.kt b/app/src/main/java/org/autojs/autojs/inrt/autojs/GlobalKeyObserver.kt
new file mode 100644
index 00000000..bc3af708
--- /dev/null
+++ b/app/src/main/java/org/autojs/autojs/inrt/autojs/GlobalKeyObserver.kt
@@ -0,0 +1,93 @@
+package org.autojs.autojs.inrt.autojs
+
+import android.util.Log
+import android.view.KeyEvent
+
+import org.autojs.autojs.app.GlobalAppContext
+import org.autojs.autojs.inrt.Pref
+import org.autojs.autojs.core.accessibility.AccessibilityService
+import org.autojs.autojs.core.accessibility.OnKeyListener
+import org.autojs.autojs.core.inputevent.InputEventObserver
+import org.autojs.autojs.core.inputevent.ShellKeyObserver
+
+
+/**
+ * Created by Stardust on 2017/8/14.
+ */
+class GlobalKeyObserver internal constructor() : OnKeyListener, ShellKeyObserver.KeyListener {
+ private var mVolumeDownFromShell: Boolean = false
+ private var mVolumeDownFromAccessibility: Boolean = false
+ private var mVolumeUpFromShell: Boolean = false
+ private var mVolumeUpFromAccessibility: Boolean = false
+
+ init {
+ AccessibilityService.stickOnKeyObserver
+ .addListener(this)
+ val observer = ShellKeyObserver()
+ observer.setKeyListener(this)
+ InputEventObserver.getGlobal(GlobalAppContext.get()).addListener(observer)
+ }
+
+ fun onVolumeUp() {
+ Log.d(LOG_TAG, "onVolumeUp at " + System.currentTimeMillis())
+ if (Pref.shouldStopAllScriptsWhenVolumeUp()) {
+ AutoJs.instance.scriptEngineService.stopAllAndToast()
+ }
+ }
+
+ override fun onKeyEvent(keyCode: Int, event: KeyEvent) {
+ if (event.action != KeyEvent.ACTION_UP)
+ return
+ if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) {
+ if (mVolumeDownFromShell) {
+ mVolumeDownFromShell = false
+ return
+ }
+ mVolumeUpFromAccessibility = true
+ onVolumeDown()
+ } else if (keyCode == KeyEvent.KEYCODE_VOLUME_UP) {
+ if (mVolumeUpFromShell) {
+ mVolumeUpFromShell = false
+ return
+ }
+ mVolumeUpFromAccessibility = true
+ onVolumeUp()
+ }
+ }
+
+ fun onVolumeDown() {
+
+ }
+
+
+ override fun onKeyDown(keyName: String) {
+
+ }
+
+ override fun onKeyUp(keyName: String) {
+ if ("KEY_VOLUMEUP" == keyName) {
+ if (mVolumeUpFromAccessibility) {
+ mVolumeUpFromAccessibility = false
+ return
+ }
+ mVolumeUpFromShell = true
+ onVolumeUp()
+ } else if ("KEY_VOLUMEDOWN" == keyName) {
+ if (mVolumeDownFromAccessibility) {
+ mVolumeDownFromAccessibility = false
+ return
+ }
+ mVolumeDownFromShell = true
+ onVolumeDown()
+ }
+ }
+
+ companion object {
+ private const val LOG_TAG = "GlobalKeyObserver"
+ private val sSingleton = GlobalKeyObserver()
+
+ fun init() {
+ //do nothing
+ }
+ }
+}
diff --git a/app/src/main/java/org/autojs/autojs/inrt/autojs/ScriptExecutionGlobalListener.kt b/app/src/main/java/org/autojs/autojs/inrt/autojs/ScriptExecutionGlobalListener.kt
new file mode 100644
index 00000000..b6ed525d
--- /dev/null
+++ b/app/src/main/java/org/autojs/autojs/inrt/autojs/ScriptExecutionGlobalListener.kt
@@ -0,0 +1,36 @@
+package org.autojs.autojs.inrt.autojs
+
+import org.autojs.autojs.app.GlobalAppContext
+import org.autojs.autojs.execution.ScriptExecution
+import org.autojs.autojs.execution.ScriptExecutionListener
+import org.autojs.autojs6.R
+
+/**
+ * Created by Stardust on 2017/5/3.
+ */
+class ScriptExecutionGlobalListener : ScriptExecutionListener {
+
+ override fun onStart(execution: ScriptExecution) {
+ execution.engine.setTag(ENGINE_TAG_START_TIME, System.currentTimeMillis())
+ }
+
+ override fun onSuccess(execution: ScriptExecution, result: Any?) {
+ onFinish(execution)
+ }
+
+ private fun onFinish(execution: ScriptExecution) {
+ val millis = execution.engine.getTag(ENGINE_TAG_START_TIME) as Long? ?: return
+ val seconds = (System.currentTimeMillis() - millis) / 1000.0
+ AutoJs.instance.scriptEngineService.globalConsole
+ .verbose(GlobalAppContext.get().getString(R.string.text_execution_finished), execution.source.toString(), seconds)
+ }
+
+ override fun onException(execution: ScriptExecution, e: Throwable) {
+ onFinish(execution)
+ }
+
+ companion object {
+ private const val ENGINE_TAG_START_TIME = "start_time"
+ }
+
+}
diff --git a/app/src/main/java/org/autojs/autojs/inrt/autojs/XJavaScriptEngine.kt b/app/src/main/java/org/autojs/autojs/inrt/autojs/XJavaScriptEngine.kt
new file mode 100644
index 00000000..9dcb0402
--- /dev/null
+++ b/app/src/main/java/org/autojs/autojs/inrt/autojs/XJavaScriptEngine.kt
@@ -0,0 +1,44 @@
+package org.autojs.autojs.inrt.autojs
+
+import android.content.Context
+import org.autojs.autojs.engine.LoopBasedJavaScriptEngine
+import org.autojs.autojs.engine.encryption.ScriptEncryption
+import org.autojs.autojs.pio.PFiles
+import org.autojs.autojs.script.EncryptedScriptFileHeader
+import org.autojs.autojs.script.JavaScriptFileSource
+import org.autojs.autojs.script.ScriptSource
+import org.autojs.autojs.script.StringScriptSource
+import java.io.File
+import java.security.GeneralSecurityException
+
+class XJavaScriptEngine(context: Context) : LoopBasedJavaScriptEngine(context) {
+
+
+ override fun execute(source: ScriptSource, callback: ExecuteCallback?) {
+ if (source is JavaScriptFileSource) {
+ try {
+ if (execute(source.file)) {
+ return
+ }
+ } catch (e: Throwable) {
+ e.printStackTrace()
+ return
+ }
+ }
+ super.execute(source, callback)
+ }
+
+ private fun execute(file: File): Boolean {
+ val bytes = PFiles.readBytes(file.path)
+ if (!EncryptedScriptFileHeader.isValidFile(bytes)) {
+ return false
+ }
+ try {
+ super.execute(StringScriptSource(file.name, String(ScriptEncryption.decrypt(bytes, EncryptedScriptFileHeader.BLOCK_SIZE))))
+ } catch (e: GeneralSecurityException) {
+ e.printStackTrace()
+ }
+ return true
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/autojs/autojs/inrt/launch/AssetsProjectLauncher.kt b/app/src/main/java/org/autojs/autojs/inrt/launch/AssetsProjectLauncher.kt
new file mode 100644
index 00000000..44d71563
--- /dev/null
+++ b/app/src/main/java/org/autojs/autojs/inrt/launch/AssetsProjectLauncher.kt
@@ -0,0 +1,110 @@
+package org.autojs.autojs.inrt.launch
+
+import android.app.Activity
+import android.content.Context
+import android.content.Intent
+import android.os.Handler
+import android.os.Looper
+import android.text.TextUtils
+import org.autojs.autojs.inrt.LogActivity
+import org.autojs.autojs.inrt.Pref
+import org.autojs.autojs.AutoJs
+import org.autojs.autojs.engine.encryption.ScriptEncryption
+import org.autojs.autojs.execution.ExecutionConfig
+import org.autojs.autojs.execution.ScriptExecution
+import org.autojs.autojs.pio.PFiles
+import org.autojs.autojs.pio.UncheckedIOException
+import org.autojs.autojs.project.ProjectConfig
+import org.autojs.autojs.script.JavaScriptFileSource
+import org.autojs.autojs.script.JavaScriptSource
+import java.io.File
+import java.io.IOException
+
+/**
+ * Created by Stardust on 2018/1/24.
+ */
+open class AssetsProjectLauncher(private val mAssetsProjectDir: String, private val mActivity: Context) {
+ private val mProjectDir: String = File(mActivity.filesDir, "project/").path
+ private val mProjectConfig: ProjectConfig = ProjectConfig.fromAssets(mActivity, ProjectConfig.configFileOfDir(mAssetsProjectDir))
+ private val mMainScriptFile: File = File(mProjectDir, mProjectConfig.mainScriptFile)
+ private val mHandler: Handler = Handler(Looper.getMainLooper())
+ private var mScriptExecution: ScriptExecution? = null
+
+ init {
+ prepare()
+ }
+
+ fun launch(activity: Activity) {
+ //如果需要隐藏日志界面,则直接运行脚本
+ if (mProjectConfig.launchConfig.shouldHideLogs() || Pref.shouldHideLogs()) {
+ runScript(activity)
+ } else {
+ //如果不隐藏日志界面
+ //如果当前已经是日志界面则直接运行脚本
+ if (activity is LogActivity) {
+ runScript(null)
+ } else {
+ //否则显示日志界面并在日志界面中运行脚本
+ mHandler.post {
+ activity.startActivity(Intent(mActivity, LogActivity::class.java)
+ .putExtra(LogActivity.EXTRA_LAUNCH_SCRIPT, true))
+ activity.finish()
+ }
+ }
+ }
+ }
+
+ private fun runScript(activity: Activity?) {
+ if (mScriptExecution != null && mScriptExecution!!.engine != null &&
+ !mScriptExecution!!.engine.isDestroyed) {
+ return
+ }
+ try {
+ val source = JavaScriptFileSource("main", mMainScriptFile)
+ val config = ExecutionConfig(workingDirectory = mProjectDir)
+ if (source.executionMode and JavaScriptSource.EXECUTION_MODE_UI != 0) {
+ config.intentFlags = Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_TASK_ON_HOME
+ } else {
+ activity?.finish()
+ }
+ mScriptExecution = AutoJs.instance.scriptEngineService.execute(source, config)
+ } catch (e: Exception) {
+ AutoJs.instance.globalConsole.error(e)
+ }
+
+ }
+
+ private fun prepare() {
+ val projectConfigPath = PFiles.join(mProjectDir, ProjectConfig.CONFIG_FILE_NAME)
+ val projectConfig = ProjectConfig.fromFile(projectConfigPath)
+ if (projectConfig != null &&
+ TextUtils.equals(projectConfig.buildInfo.buildId, mProjectConfig.buildInfo.buildId)) {
+ initKey(projectConfig)
+ return
+ }
+ initKey(mProjectConfig)
+ PFiles.deleteRecursively(File(mProjectDir))
+ try {
+ PFiles.copyAssetDir(mActivity.assets, mAssetsProjectDir, mProjectDir, null)
+ } catch (e: IOException) {
+ throw UncheckedIOException(e)
+ }
+ }
+
+ private fun initKey(projectConfig: ProjectConfig) {
+ val key = MD5.md5(projectConfig.packageName + projectConfig.versionName + projectConfig.mainScriptFile)
+ val vec = MD5.md5(projectConfig.buildInfo.buildId + projectConfig.name).substring(0, 16)
+ try {
+ val fieldKey = ScriptEncryption::class.java.getDeclaredField("mKey")
+ fieldKey.isAccessible = true
+ fieldKey.set(null, key)
+ val fieldVector = ScriptEncryption::class.java.getDeclaredField("mInitVector")
+ fieldVector.isAccessible = true
+ fieldVector.set(null, vec)
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+
+ }
+
+}
diff --git a/app/src/main/java/org/autojs/autojs/inrt/launch/GlobalProjectLauncher.kt b/app/src/main/java/org/autojs/autojs/inrt/launch/GlobalProjectLauncher.kt
new file mode 100644
index 00000000..dc170910
--- /dev/null
+++ b/app/src/main/java/org/autojs/autojs/inrt/launch/GlobalProjectLauncher.kt
@@ -0,0 +1,10 @@
+package org.autojs.autojs.inrt.launch
+
+import android.annotation.SuppressLint
+import org.autojs.autojs.app.GlobalAppContext
+
+/**
+ * Created by Stardust on 2018/3/21.
+ */
+@SuppressLint("StaticFieldLeak")
+object GlobalProjectLauncher: AssetsProjectLauncher("project", GlobalAppContext.get())
diff --git a/app/src/main/java/org/autojs/autojs/inrt/launch/MD5.java b/app/src/main/java/org/autojs/autojs/inrt/launch/MD5.java
new file mode 100644
index 00000000..94b3584e
--- /dev/null
+++ b/app/src/main/java/org/autojs/autojs/inrt/launch/MD5.java
@@ -0,0 +1,31 @@
+package org.autojs.autojs.inrt.launch;
+
+import java.security.MessageDigest;
+
+public class MD5 {
+
+ public static byte[] md5Bytes(String message) {
+ try {
+ MessageDigest md5 = MessageDigest.getInstance("MD5");
+ md5.update(message.getBytes());
+ return md5.digest();
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public static String md5(String message) {
+ byte[] bytes = md5Bytes(message);
+ StringBuilder hexString = new StringBuilder(32);
+ for (byte b : bytes) {
+ String hex = Integer.toHexString(0xFF & b);
+ if (hex.length() == 1) {
+ hexString.append('0');
+ }
+ hexString.append(hex);
+ }
+ return hexString.toString();
+
+
+ }
+}
diff --git a/app/src/main/res/layout/activity_main_inrt.xml b/app/src/main/res/layout/activity_main_inrt.xml
new file mode 100644
index 00000000..14b9d00f
--- /dev/null
+++ b/app/src/main/res/layout/activity_main_inrt.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_settings_inrt.xml b/app/src/main/res/layout/activity_settings_inrt.xml
new file mode 100644
index 00000000..20175b9c
--- /dev/null
+++ b/app/src/main/res/layout/activity_settings_inrt.xml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_splash_inrt.xml b/app/src/main/res/layout/activity_splash_inrt.xml
new file mode 100644
index 00000000..1b3de0b0
--- /dev/null
+++ b/app/src/main/res/layout/activity_splash_inrt.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/menu/menu_main_inrt.xml b/app/src/main/res/menu/menu_main_inrt.xml
new file mode 100644
index 00000000..d692ebb8
--- /dev/null
+++ b/app/src/main/res/menu/menu_main_inrt.xml
@@ -0,0 +1,7 @@
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/attrs.xml b/app/src/main/res/values/attrs.xml
index 29872499..cf3a65ff 100644
--- a/app/src/main/res/values/attrs.xml
+++ b/app/src/main/res/values/attrs.xml
@@ -75,4 +75,12 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/xml/preference_inrt.xml b/app/src/main/res/xml/preference_inrt.xml
new file mode 100644
index 00000000..25e87e6e
--- /dev/null
+++ b/app/src/main/res/xml/preference_inrt.xml
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/xml/provider_paths.xml b/app/src/main/res/xml/provider_paths.xml
index 3e5ddda3..aae5c0bb 100644
--- a/app/src/main/res/xml/provider_paths.xml
+++ b/app/src/main/res/xml/provider_paths.xml
@@ -1,6 +1,7 @@
-
+
+
\ No newline at end of file