重构 转换inrt模块为kotlin

修复 打包后首次运行没有任何效果的问题
This commit is contained in:
hyb1996 2018-12-04 14:19:06 +08:00
parent e4de1e0aaa
commit 8d052d2b6f
23 changed files with 746 additions and 787 deletions

View File

@ -1,84 +0,0 @@
package com.stardust.auojs.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 com.stardust.app.GlobalAppContext;
import com.stardust.auojs.inrt.autojs.AutoJs;
import com.stardust.auojs.inrt.autojs.GlobalKeyObserver;
import com.stardust.autojs.core.ui.inflater.ImageLoader;
import com.stardust.autojs.core.ui.inflater.util.Drawables;
/**
* Created by Stardust on 2017/7/1.
*/
public class App extends Application {
@Override
public void onCreate() {
super.onCreate();
GlobalAppContext.set(this);
AutoJs.initInstance(this);
GlobalKeyObserver.init();
Drawables.setDefaultImageLoader(new ImageLoader() {
@Override
public void loadInto(ImageView imageView, Uri uri) {
Glide.with(App.this)
.load(uri)
.into(imageView);
}
@Override
public void loadIntoBackground(View view, Uri uri) {
Glide.with(App.this)
.load(uri)
.into(new SimpleTarget<Drawable>() {
@Override
public void onResourceReady(Drawable resource, Transition<? super Drawable> transition) {
view.setBackground(resource);
}
});
}
@Override
public Drawable load(View view, Uri uri) {
throw new UnsupportedOperationException();
}
@Override
public void load(View view, Uri uri, DrawableCallback drawableCallback) {
Glide.with(App.this)
.load(uri)
.into(new SimpleTarget<Drawable>() {
@Override
public void onResourceReady(Drawable resource, Transition<? super Drawable> transition) {
drawableCallback.onLoaded(resource);
}
});
}
@Override
public void load(View view, Uri uri, BitmapCallback bitmapCallback) {
Glide.with(App.this)
.asBitmap()
.load(uri)
.into(new SimpleTarget<Bitmap>() {
@Override
public void onResourceReady(Bitmap resource, Transition<? super Bitmap> transition) {
bitmapCallback.onLoaded(resource);
}
});
}
});
}
}

View File

@ -0,0 +1,74 @@
package com.stardust.auojs.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 com.stardust.app.GlobalAppContext
import com.stardust.auojs.inrt.autojs.AutoJs
import com.stardust.auojs.inrt.autojs.GlobalKeyObserver
import com.stardust.autojs.core.ui.inflater.ImageLoader
import com.stardust.autojs.core.ui.inflater.util.Drawables
/**
* Created by Stardust on 2017/7/1.
*/
class App : Application() {
override fun onCreate() {
super.onCreate()
GlobalAppContext.set(this)
AutoJs.initInstance(this)
GlobalKeyObserver.init()
Drawables.setDefaultImageLoader(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<Drawable>() {
override fun onResourceReady(resource: Drawable, transition: Transition<in Drawable>) {
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<Drawable>() {
override fun onResourceReady(resource: Drawable, transition: Transition<in Drawable>) {
drawableCallback.onLoaded(resource)
}
})
}
override fun load(view: View, uri: Uri, bitmapCallback: ImageLoader.BitmapCallback) {
Glide.with(this@App)
.asBitmap()
.load(uri)
.into(object : SimpleTarget<Bitmap>() {
override fun onResourceReady(resource: Bitmap, transition: Transition<in Bitmap>) {
bitmapCallback.onLoaded(resource)
}
})
}
})
}
}

View File

@ -1,50 +0,0 @@
package com.stardust.auojs.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 com.stardust.auojs.inrt.autojs.AutoJs;
import com.stardust.auojs.inrt.launch.GlobalProjectLauncher;
import com.stardust.autojs.core.console.ConsoleView;
import com.stardust.autojs.core.console.ConsoleImpl;
public class LogActivity extends AppCompatActivity {
public static final String EXTRA_LAUNCH_SCRIPT = "launch_script";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setupView();
if (getIntent().getBooleanExtra(EXTRA_LAUNCH_SCRIPT, false)) {
GlobalProjectLauncher.getInstance().launch(this);
}
}
private void setupView() {
setContentView(R.layout.activity_main);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
ConsoleView consoleView = findViewById(R.id.console);
consoleView.setConsole((ConsoleImpl) AutoJs.getInstance().getGlobalConsole());
consoleView.findViewById(R.id.input_container).setVisibility(View.GONE);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
startActivity(new Intent(this, SettingsActivity.class));
return true;
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
}

View File

@ -0,0 +1,50 @@
package com.stardust.auojs.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 com.stardust.auojs.inrt.autojs.AutoJs
import com.stardust.auojs.inrt.launch.GlobalProjectLauncher
import com.stardust.autojs.core.console.ConsoleView
import com.stardust.autojs.core.console.ConsoleImpl
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)
val toolbar = findViewById<Toolbar>(R.id.toolbar)
setSupportActionBar(toolbar)
val consoleView = findViewById<ConsoleView>(R.id.console)
consoleView.setConsole(AutoJs.instance.globalConsole as ConsoleImpl)
consoleView.findViewById<View>(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, menu)
return true
}
companion object {
val EXTRA_LAUNCH_SCRIPT = "launch_script"
}
}

View File

@ -1,46 +0,0 @@
package com.stardust.auojs.inrt;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import com.stardust.app.GlobalAppContext;
/**
* Created by Stardust on 2017/12/8.
*/
public class Pref {
private static final String KEY_FIRST_USING = "key_first_using";
private static SharedPreferences sPreferences;
public static SharedPreferences getPreferences() {
if (sPreferences == null)
sPreferences = PreferenceManager.getDefaultSharedPreferences(GlobalAppContext.get());
return sPreferences;
}
private static String getString(int res) {
return GlobalAppContext.getString(res);
}
public static boolean shouldEnableAccessibilityServiceByRoot() {
return getPreferences().getBoolean(getString(R.string.key_enable_accessibility_service_by_root), false);
}
public static boolean shouldHideLogs() {
return getPreferences().getBoolean(getString(R.string.key_dont_show_main_activity), false);
}
public static boolean shouldStopAllScriptsWhenVolumeUp() {
return getPreferences().getBoolean(getString(R.string.key_use_volume_control_running), true);
}
public static boolean isFirstUsing() {
boolean firstUsing = getPreferences().getBoolean(KEY_FIRST_USING, true);
if (firstUsing) {
getPreferences().edit().putBoolean(KEY_FIRST_USING, false).apply();
}
return firstUsing;
}
}

View File

@ -0,0 +1,48 @@
package com.stardust.auojs.inrt
import android.content.SharedPreferences
import android.preference.PreferenceManager
import com.stardust.app.GlobalAppContext
/**
* Created by Stardust on 2017/12/8.
*/
object Pref {
private const val KEY_FIRST_USING = "key_first_using"
private var sPreferences: SharedPreferences? = null
val preferences: SharedPreferences?
get() {
if (sPreferences == null)
sPreferences = PreferenceManager.getDefaultSharedPreferences(GlobalAppContext.get())
return sPreferences
}
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.getString(res)
}
fun shouldEnableAccessibilityServiceByRoot(): Boolean {
return preferences!!.getBoolean(getString(R.string.key_enable_accessibility_service_by_root), false)
}
fun shouldHideLogs(): Boolean {
return preferences!!.getBoolean(getString(R.string.key_dont_show_main_activity), false)
}
fun shouldStopAllScriptsWhenVolumeUp(): Boolean {
return preferences!!.getBoolean(getString(R.string.key_use_volume_control_running), true)
}
}

View File

@ -1,47 +0,0 @@
package com.stardust.auojs.inrt;
import android.os.Bundle;
import android.preference.Preference;
import android.preference.PreferenceScreen;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
/**
* Created by Stardust on 2017/12/8.
*/
public class SettingsActivity extends AppCompatActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setupViews();
}
private void setupViews() {
setContentView(R.layout.activity_settings);
getFragmentManager().beginTransaction().replace(R.id.fragment_setting, new PreferenceFragment()).commit();
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
toolbar.setTitle(R.string.text_settings);
setSupportActionBar(toolbar);
toolbar.setNavigationOnClickListener(v -> finish());
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
public static class PreferenceFragment extends android.preference.PreferenceFragment {
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preference);
}
@Override
public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
return super.onPreferenceTreeClick(preferenceScreen, preference);
}
}
}

View File

@ -0,0 +1,38 @@
package com.stardust.auojs.inrt
import android.os.Bundle
import androidx.annotation.Nullable
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.Toolbar
/**
* 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)
fragmentManager.beginTransaction().replace(R.id.fragment_setting, PreferenceFragment()).commit()
val toolbar = findViewById<Toolbar>(R.id.toolbar)
toolbar.setTitle(R.string.text_settings)
setSupportActionBar(toolbar)
toolbar.setNavigationOnClickListener { v -> finish() }
supportActionBar?.setDisplayHomeAsUpEnabled(true)
}
class PreferenceFragment : android.preference.PreferenceFragment() {
override fun onCreate(@Nullable savedInstanceState: Bundle) {
super.onCreate(savedInstanceState)
addPreferencesFromResource(R.xml.preference)
}
}
}

View File

@ -1,98 +0,0 @@
package com.stardust.auojs.inrt;
import android.Manifest;
import android.content.Intent;
import android.graphics.Typeface;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import android.widget.TextView;
import android.widget.Toast;
import com.stardust.auojs.inrt.autojs.AutoJs;
import com.stardust.auojs.inrt.launch.GlobalProjectLauncher;
import java.util.ArrayList;
import java.util.List;
import static android.content.pm.PackageManager.PERMISSION_DENIED;
/**
* Created by Stardust on 2018/2/2.
*/
public class SplashActivity extends AppCompatActivity {
private static final int PERMISSION_REQUEST_CODE = 11186;
private static final long INIT_TIMEOUT = 2500;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash);
TextView slug = findViewById(R.id.slug);
slug.setTypeface(Typeface.createFromAsset(getAssets(), "roboto_medium.ttf"));
if (!Pref.isFirstUsing()) {
main();
}else {
new Handler().postDelayed(SplashActivity.this::main, INIT_TIMEOUT);
}
}
private void main() {
checkPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_PHONE_STATE);
}
private void runScript() {
new Thread(() -> {
try {
GlobalProjectLauncher.getInstance().launch(this);
} catch (Exception e) {
e.printStackTrace();
runOnUiThread(() -> {
Toast.makeText(SplashActivity.this, e.getMessage(), Toast.LENGTH_LONG).show();
startActivity(new Intent(SplashActivity.this, LogActivity.class));
AutoJs.getInstance().getGlobalConsole().printAllStackTrace(e);
});
}
}).start();
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
runScript();
}
protected void checkPermission(String... permissions) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
String[] requestPermissions = getRequestPermissions(permissions);
if (requestPermissions.length > 0) {
requestPermissions(requestPermissions, PERMISSION_REQUEST_CODE);
} else {
runScript();
}
} else {
runScript();
}
}
@RequiresApi(api = Build.VERSION_CODES.M)
private String[] getRequestPermissions(String[] permissions) {
List<String> list = new ArrayList<>();
for (String permission : permissions) {
if (checkSelfPermission(permission) == PERMISSION_DENIED) {
list.add(permission);
}
}
return list.toArray(new String[list.size()]);
}
}

View File

@ -0,0 +1,98 @@
package com.stardust.auojs.inrt
import android.Manifest
import android.content.Intent
import android.graphics.Typeface
import android.os.Build
import android.os.Bundle
import android.os.Handler
import androidx.annotation.NonNull
import androidx.annotation.Nullable
import androidx.annotation.RequiresApi
import androidx.appcompat.app.AppCompatActivity
import android.widget.TextView
import android.widget.Toast
import com.stardust.auojs.inrt.autojs.AutoJs
import com.stardust.auojs.inrt.launch.GlobalProjectLauncher
import java.util.ArrayList
import android.content.pm.PackageManager.PERMISSION_DENIED
/**
* Created by Stardust on 2018/2/2.
*/
class SplashActivity : AppCompatActivity() {
override fun onCreate(@Nullable savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_splash)
val slug = findViewById<TextView>(R.id.slug)
slug.typeface = Typeface.createFromAsset(assets, "roboto_medium.ttf")
if (!Pref.isFirstUsing) {
main()
} else {
Handler().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<String>, @NonNull grantResults: IntArray) {
runScript()
}
private fun checkPermission(vararg permissions: String) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
val requestPermissions = getRequestPermissions(permissions)
if (requestPermissions.isNotEmpty()) {
requestPermissions(requestPermissions, PERMISSION_REQUEST_CODE)
} else {
runScript()
}
} else {
runScript()
}
}
@RequiresApi(api = Build.VERSION_CODES.M)
private fun getRequestPermissions(permissions: Array<out String>): Array<String> {
val list = ArrayList<String>()
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 = 2500
}
}

View File

@ -1,52 +0,0 @@
package com.stardust.auojs.inrt.autojs;
import android.accessibilityservice.AccessibilityService;
import android.content.Context;
import android.content.Intent;
import android.provider.Settings;
import android.text.TextUtils;
import com.stardust.app.GlobalAppContext;
import com.stardust.auojs.inrt.App;
import com.stardust.autojs.core.util.ProcessShell;
import java.util.Locale;
/**
* Created by Stardust on 2017/7/1.
*/
public class AccessibilityServiceTool {
private static final String cmd = "enabled=$(settings get secure enabled_accessibility_services)\n" +
"pkg=%s\n" +
"if [[ $enabled == *$pkg* ]]\n" +
"then\n" +
"echo already_enabled\n" +
"else\n" +
"enabled=$pkg:$enabled\n" +
"settings put secure enabled_accessibility_services $enabled\n" +
"fi";
public static boolean enableAccessibilityServiceByRoot(Context context, Class<? extends AccessibilityService> accessibilityService) {
String serviceName = context.getPackageName() + "/" + accessibilityService.getName();
try {
return TextUtils.isEmpty(ProcessShell.execCommand(String.format(Locale.getDefault(), cmd, serviceName), true).error);
} catch (Exception ignored) {
return false;
}
}
public static boolean enableAccessibilityServiceByRootAndWaitFor(Context context, long timeOut) {
if (enableAccessibilityServiceByRoot(context, com.stardust.view.accessibility.AccessibilityService.class)) {
com.stardust.view.accessibility.AccessibilityService.Companion.waitForEnabled(timeOut);
return true;
}
return false;
}
public static void goToAccessibilitySetting() {
GlobalAppContext.get().startActivity(new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
}
}

View File

@ -0,0 +1,53 @@
package com.stardust.auojs.inrt.autojs
import android.accessibilityservice.AccessibilityService
import android.content.Context
import android.content.Intent
import android.provider.Settings
import android.text.TextUtils
import com.stardust.app.GlobalAppContext
import com.stardust.auojs.inrt.App
import com.stardust.autojs.core.util.ProcessShell
import java.util.Locale
/**
* Created by Stardust on 2017/7/1.
*/
object AccessibilityServiceTool {
private val cmd = "enabled=$(settings get secure enabled_accessibility_services)\n" +
"pkg=%s\n" +
"if [[ \$enabled == *\$pkg* ]]\n" +
"then\n" +
"echo already_enabled\n" +
"else\n" +
"enabled=\$pkg:\$enabled\n" +
"settings put secure enabled_accessibility_services \$enabled\n" +
"fi"
fun enableAccessibilityServiceByRoot(context: Context, accessibilityService: Class<out AccessibilityService>): Boolean {
val serviceName = context.packageName + "/" + accessibilityService.name
return try {
TextUtils.isEmpty(ProcessShell.execCommand(String.format(Locale.getDefault(), cmd, serviceName), true).error)
} catch (ignored: Exception) {
false
}
}
fun enableAccessibilityServiceByRootAndWaitFor(context: Context, timeOut: Long): Boolean {
if (enableAccessibilityServiceByRoot(context, com.stardust.view.accessibility.AccessibilityService::class.java)) {
com.stardust.view.accessibility.AccessibilityService.waitForEnabled(timeOut)
return true
}
return false
}
fun goToAccessibilitySetting() {
GlobalAppContext.get().startActivity(Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK))
}
}

View File

@ -1,122 +0,0 @@
package com.stardust.auojs.inrt.autojs;
import android.app.Application;
import android.content.Context;
import com.stardust.app.GlobalAppContext;
import com.stardust.auojs.inrt.App;
import com.stardust.auojs.inrt.LogActivity;
import com.stardust.auojs.inrt.Pref;
import com.stardust.auojs.inrt.R;
import com.stardust.auojs.inrt.SettingsActivity;
import com.stardust.autojs.engine.LoopBasedJavaScriptEngine;
import com.stardust.autojs.runtime.ScriptRuntime;
import com.stardust.autojs.runtime.api.AppUtils;
import com.stardust.autojs.runtime.exception.ScriptException;
import com.stardust.autojs.runtime.exception.ScriptInterruptedException;
import com.stardust.autojs.script.JavaScriptSource;
import com.stardust.view.accessibility.AccessibilityService;
import com.stardust.view.accessibility.AccessibilityServiceUtils;
/**
* Created by Stardust on 2017/4/2.
*/
public class AutoJs extends com.stardust.autojs.AutoJs {
private static AutoJs instance;
private String mKey = "";
private String mInitVector = "";
public static AutoJs getInstance() {
return instance;
}
public static void initInstance(Application application) {
instance = new AutoJs(application);
}
private AutoJs(Application application) {
super(application);
getScriptEngineService().registerGlobalScriptExecutionListener(new ScriptExecutionGlobalListener());
}
@Override
protected AppUtils createAppUtils(Context context) {
return new AppUtils(context, context.getPackageName() + ".fileprovider");
}
@Override
public void ensureAccessibilityServiceEnabled() {
if (AccessibilityService.Companion.getInstance() != null) {
return;
}
String errorMessage = null;
if (AccessibilityServiceUtils.INSTANCE.isAccessibilityServiceEnabled(getApplication(), AccessibilityService.class)) {
errorMessage = GlobalAppContext.getString(R.string.text_auto_operate_service_enabled_but_not_running);
} else {
if (Pref.shouldEnableAccessibilityServiceByRoot()) {
if (!AccessibilityServiceTool.enableAccessibilityServiceByRootAndWaitFor(getApplication(), 2000)) {
errorMessage = GlobalAppContext.getString(R.string.text_enable_accessibility_service_by_root_timeout);
}
} else {
errorMessage = GlobalAppContext.getString(R.string.text_no_accessibility_permission);
}
}
if (errorMessage != null) {
AccessibilityServiceTool.goToAccessibilitySetting();
throw new ScriptException(errorMessage);
}
}
@Override
public void waitForAccessibilityServiceEnabled() {
if (AccessibilityService.Companion.getInstance() != null) {
return;
}
String errorMessage = null;
if (AccessibilityServiceUtils.INSTANCE.isAccessibilityServiceEnabled(getApplication(), AccessibilityService.class)) {
errorMessage = GlobalAppContext.getString(R.string.text_auto_operate_service_enabled_but_not_running);
} else {
if (Pref.shouldEnableAccessibilityServiceByRoot()) {
if (!AccessibilityServiceTool.enableAccessibilityServiceByRootAndWaitFor(getApplication(), 2000)) {
errorMessage = GlobalAppContext.getString(R.string.text_enable_accessibility_service_by_root_timeout);
}
} else {
errorMessage = GlobalAppContext.getString(R.string.text_no_accessibility_permission);
}
}
if (errorMessage != null) {
AccessibilityServiceTool.goToAccessibilitySetting();
if (!AccessibilityService.Companion.waitForEnabled(-1)) {
throw new ScriptInterruptedException();
}
}
}
@Override
protected void initScriptEngineManager() {
super.initScriptEngineManager();
getScriptEngineManager().registerEngine(JavaScriptSource.ENGINE, () -> {
XJavaScriptEngine engine = new XJavaScriptEngine(getApplication());
engine.setKey(mKey, mInitVector);
engine.setRuntime(createRuntime());
return engine;
});
}
@Override
protected ScriptRuntime createRuntime() {
ScriptRuntime runtime = super.createRuntime();
runtime.putProperty("class.settings", SettingsActivity.class);
runtime.putProperty("class.console", LogActivity.class);
return runtime;
}
public void setKey(String key, String vet) {
mKey = key;
mInitVector = vet;
}
}

View File

@ -0,0 +1,116 @@
package com.stardust.auojs.inrt.autojs
import android.annotation.SuppressLint
import android.app.Application
import android.content.Context
import com.stardust.app.GlobalAppContext
import com.stardust.auojs.inrt.LogActivity
import com.stardust.auojs.inrt.Pref
import com.stardust.auojs.inrt.R
import com.stardust.auojs.inrt.SettingsActivity
import com.stardust.autojs.runtime.ScriptRuntime
import com.stardust.autojs.runtime.api.AppUtils
import com.stardust.autojs.runtime.exception.ScriptException
import com.stardust.autojs.runtime.exception.ScriptInterruptedException
import com.stardust.autojs.script.JavaScriptSource
import com.stardust.view.accessibility.AccessibilityService
import com.stardust.view.accessibility.AccessibilityServiceUtils
import java.lang.IllegalStateException
/**
* Created by Stardust on 2017/4/2.
*/
class AutoJs private constructor(application: Application) : com.stardust.autojs.AutoJs(application) {
private var mKey = ""
private var mInitVector = ""
init {
scriptEngineService.registerGlobalScriptExecutionListener(ScriptExecutionGlobalListener())
}
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 (AccessibilityServiceUtils.isAccessibilityServiceEnabled(application, AccessibilityService::class.java)) {
errorMessage = GlobalAppContext.getString(R.string.text_auto_operate_service_enabled_but_not_running)
} else {
if (Pref.shouldEnableAccessibilityServiceByRoot()) {
if (!AccessibilityServiceTool.enableAccessibilityServiceByRootAndWaitFor(application, 2000)) {
errorMessage = GlobalAppContext.getString(R.string.text_enable_accessibility_service_by_root_timeout)
}
} else {
errorMessage = GlobalAppContext.getString(R.string.text_no_accessibility_permission)
}
}
if (errorMessage != null) {
AccessibilityServiceTool.goToAccessibilitySetting()
throw ScriptException(errorMessage)
}
}
override fun waitForAccessibilityServiceEnabled() {
if (AccessibilityService.instance != null) {
return
}
var errorMessage: String? = null
if (AccessibilityServiceUtils.isAccessibilityServiceEnabled(application, AccessibilityService::class.java)) {
errorMessage = GlobalAppContext.getString(R.string.text_auto_operate_service_enabled_but_not_running)
} else {
if (Pref.shouldEnableAccessibilityServiceByRoot()) {
if (!AccessibilityServiceTool.enableAccessibilityServiceByRootAndWaitFor(application, 2000)) {
errorMessage = GlobalAppContext.getString(R.string.text_enable_accessibility_service_by_root_timeout)
}
} else {
errorMessage = GlobalAppContext.getString(R.string.text_no_accessibility_permission)
}
}
if (errorMessage != null) {
AccessibilityServiceTool.goToAccessibilitySetting()
if (!AccessibilityService.waitForEnabled(-1)) {
throw ScriptInterruptedException()
}
}
}
override fun initScriptEngineManager() {
super.initScriptEngineManager()
scriptEngineManager.registerEngine(JavaScriptSource.ENGINE) {
val engine = XJavaScriptEngine(application)
engine.setKey(mKey, mInitVector)
engine.runtime = createRuntime()
engine
}
}
override fun createRuntime(): ScriptRuntime {
val runtime = super.createRuntime()
runtime.putProperty("class.settings", SettingsActivity::class.java)
runtime.putProperty("class.console", LogActivity::class.java)
return runtime
}
fun setKey(key: String, vet: String) {
mKey = key
mInitVector = vet
}
companion object {
@SuppressLint("StaticFieldLeak")
lateinit var instance: AutoJs
private set
fun initInstance(application: Application) {
instance = AutoJs(application)
}
}
}

View File

@ -1,93 +0,0 @@
package com.stardust.auojs.inrt.autojs;
import android.util.Log;
import android.view.KeyEvent;
import com.stardust.app.GlobalAppContext;
import com.stardust.auojs.inrt.Pref;
import com.stardust.autojs.core.inputevent.InputEventObserver;
import com.stardust.autojs.core.inputevent.ShellKeyObserver;
import com.stardust.view.accessibility.AccessibilityService;
import com.stardust.view.accessibility.OnKeyListener;
/**
* Created by Stardust on 2017/8/14.
*/
public class GlobalKeyObserver implements OnKeyListener, ShellKeyObserver.KeyListener {
private static final String LOG_TAG = "GlobalKeyObserver";
private static GlobalKeyObserver sSingleton = new GlobalKeyObserver();
private boolean mVolumeDownFromShell, mVolumeDownFromAccessibility;
private boolean mVolumeUpFromShell, mVolumeUpFromAccessibility;
GlobalKeyObserver() {
AccessibilityService.Companion.getStickOnKeyObserver()
.addListener(this);
ShellKeyObserver observer = new ShellKeyObserver();
observer.setKeyListener(this);
InputEventObserver.getGlobal(GlobalAppContext.get()).addListener(observer);
}
public static void init() {
//do nothing
}
public void onVolumeUp() {
Log.d(LOG_TAG, "onVolumeUp at " + System.currentTimeMillis());
if (Pref.shouldStopAllScriptsWhenVolumeUp()) {
AutoJs.getInstance().getScriptEngineService().stopAllAndToast();
}
}
@Override
public void onKeyEvent(int keyCode, KeyEvent event) {
if (event.getAction() != 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();
}
}
public void onVolumeDown() {
}
@Override
public void onKeyDown(String keyName) {
}
@Override
public void onKeyUp(String keyName) {
if ("KEY_VOLUMEUP".equals(keyName)) {
if (mVolumeUpFromAccessibility) {
mVolumeUpFromAccessibility = false;
return;
}
mVolumeUpFromShell = true;
onVolumeUp();
} else if ("KEY_VOLUMEDOWN".equals(keyName)) {
if (mVolumeDownFromAccessibility) {
mVolumeDownFromAccessibility = false;
return;
}
mVolumeDownFromShell = true;
onVolumeDown();
}
}
}

View File

@ -0,0 +1,95 @@
package com.stardust.auojs.inrt.autojs
import android.util.Log
import android.view.KeyEvent
import com.stardust.app.GlobalAppContext
import com.stardust.auojs.inrt.Pref
import com.stardust.autojs.core.inputevent.InputEventObserver
import com.stardust.autojs.core.inputevent.ShellKeyObserver
import com.stardust.view.accessibility.AccessibilityService
import com.stardust.view.accessibility.OnKeyListener
/**
* 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 val LOG_TAG = "GlobalKeyObserver"
private val sSingleton = GlobalKeyObserver()
fun init() {
//do nothing
}
}
}

View File

@ -1,39 +0,0 @@
package com.stardust.auojs.inrt.autojs;
import com.stardust.app.GlobalAppContext;
import com.stardust.auojs.inrt.R;
import com.stardust.autojs.execution.ScriptExecution;
import com.stardust.autojs.execution.ScriptExecutionListener;
/**
* Created by Stardust on 2017/5/3.
*/
public class ScriptExecutionGlobalListener implements ScriptExecutionListener {
private static final String ENGINE_TAG_START_TIME = "org.autojs.autojs.autojs.Goodbye, World";
@Override
public void onStart(ScriptExecution execution) {
execution.getEngine().setTag(ENGINE_TAG_START_TIME, System.currentTimeMillis());
}
@Override
public void onSuccess(ScriptExecution execution, Object result) {
onFinish(execution);
}
private void onFinish(ScriptExecution execution) {
Long millis = (Long) execution.getEngine().getTag(ENGINE_TAG_START_TIME);
if (millis == null)
return;
double seconds = (System.currentTimeMillis() - millis) / 1000.0;
AutoJs.getInstance().getScriptEngineService().getGlobalConsole()
.verbose(GlobalAppContext.getString(R.string.text_execution_finished), execution.getSource().toString(), seconds);
}
@Override
public void onException(ScriptExecution execution, Throwable e) {
onFinish(execution);
}
}

View File

@ -0,0 +1,37 @@
package com.stardust.auojs.inrt.autojs
import com.stardust.app.GlobalAppContext
import com.stardust.auojs.inrt.R
import com.stardust.autojs.execution.ScriptExecution
import com.stardust.autojs.execution.ScriptExecutionListener
/**
* 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.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"
}
}

View File

@ -8,6 +8,9 @@ import com.stardust.autojs.script.StringScriptSource
import com.stardust.pio.PFiles
import com.stardust.util.AdvancedEncryptionStandard
import java.io.File
import java.lang.Exception
import java.lang.IllegalStateException
import java.security.GeneralSecurityException
class XJavaScriptEngine(context: Context) : LoopBasedJavaScriptEngine(context) {
@ -28,9 +31,12 @@ class XJavaScriptEngine(context: Context) : LoopBasedJavaScriptEngine(context) {
private fun execute(file: File) {
val bytes = PFiles.readBytes(file.path)
//val key = AdvancedEncryptionStandard(mKey.toByteArray(), mInitVector).decrypt(bytes, 0, 16)
val source = AdvancedEncryptionStandard(mKey.toByteArray(), mInitVector).decrypt(bytes)
super.execute(StringScriptSource(file.name, String(source)))
try {
val source = AdvancedEncryptionStandard(mKey.toByteArray(), mInitVector).decrypt(bytes)
super.execute(StringScriptSource(file.name, String(source)))
} catch (e: GeneralSecurityException) {
e.printStackTrace()
}
}
fun setKey(key: String, initVector: String) {

View File

@ -1,129 +0,0 @@
package com.stardust.auojs.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 com.stardust.auojs.inrt.BuildConfig;
import com.stardust.auojs.inrt.LogActivity;
import com.stardust.auojs.inrt.Pref;
import com.stardust.auojs.inrt.autojs.AutoJs;
import com.stardust.autojs.execution.ExecutionConfig;
import com.stardust.autojs.execution.ScriptExecution;
import com.stardust.autojs.project.ProjectConfig;
import com.stardust.autojs.script.JavaScriptFileSource;
import com.stardust.autojs.script.JavaScriptSource;
import com.stardust.autojs.script.ScriptSource;
import com.stardust.pio.PFiles;
import com.stardust.pio.UncheckedIOException;
import com.stardust.util.MD5;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
/**
* Created by Stardust on 2018/1/24.
*/
public class AssetsProjectLauncher {
private String mAssetsProjectDir;
private String mProjectDir;
private File mMainScriptFile;
private ProjectConfig mProjectConfig;
private Context mActivity;
private Handler mHandler;
private ScriptExecution mScriptExecution;
public AssetsProjectLauncher(String projectDir, Context context) {
mAssetsProjectDir = projectDir;
mActivity = context;
mProjectDir = new File(context.getFilesDir(), "project/").getPath();
mProjectConfig = ProjectConfig.fromAssets(context, ProjectConfig.configFileOfDir(mAssetsProjectDir));
mMainScriptFile = new File(mProjectDir, mProjectConfig.getMainScriptFile());
mHandler = new Handler(Looper.getMainLooper());
prepare();
}
public void launch(Activity activity) {
//如果需要隐藏日志界面则直接运行脚本
if (mProjectConfig.getLaunchConfig().shouldHideLogs() || Pref.shouldHideLogs()) {
runScript(activity);
} else {
//如果不隐藏日志界面
//如果当前已经是日志界面则直接运行脚本
if (activity instanceof LogActivity) {
runScript(null);
} else {
//否则显示日志界面并在日志界面中运行脚本
mHandler.post(() -> {
activity.startActivity(new Intent(mActivity, LogActivity.class)
.putExtra(LogActivity.EXTRA_LAUNCH_SCRIPT, true));
activity.finish();
});
}
}
}
private void runScript(Activity activity) {
if (mScriptExecution != null && mScriptExecution.getEngine() != null &&
!mScriptExecution.getEngine().isDestroyed()) {
return;
}
try {
JavaScriptFileSource source = new JavaScriptFileSource("main", mMainScriptFile);
ExecutionConfig config = new ExecutionConfig()
.executePath(mProjectDir);
if ((source.getExecutionMode() & JavaScriptSource.EXECUTION_MODE_UI) != 0) {
config.setIntentFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
} else {
if (activity != null) {
activity.finish();
}
}
mScriptExecution = AutoJs.getInstance().getScriptEngineService().execute(source, config);
} catch (Exception e) {
AutoJs.getInstance().getGlobalConsole().error(e);
}
}
private void prepare() {
String projectConfigPath = PFiles.join(mProjectDir, ProjectConfig.CONFIG_FILE_NAME);
ProjectConfig projectConfig = ProjectConfig.fromFile(projectConfigPath);
initKey(projectConfig);
if (!BuildConfig.DEBUG && projectConfig != null &&
TextUtils.equals(projectConfig.getBuildInfo().getBuildId(), mProjectConfig.getBuildInfo().getBuildId())) {
return;
}
PFiles.deleteRecursively(new File(mProjectDir));
try {
PFiles.copyAssetDir(mActivity.getAssets(), mAssetsProjectDir, mProjectDir, null);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
private void initKey(ProjectConfig projectConfig) {
if (projectConfig == null) {
return;
}
String key = MD5.md5(projectConfig.getPackageName() + projectConfig.getVersionName() + projectConfig.getMainScriptFile());
String vec = MD5.md5(projectConfig.getBuildInfo().getBuildId() + projectConfig.getName()).substring(0, 16);
try {
Field fieldKey = AutoJs.class.getDeclaredField("mKey");
fieldKey.setAccessible(true);
fieldKey.set(AutoJs.getInstance(), key);
Field fieldVector = AutoJs.class.getDeclaredField("mInitVector");
fieldVector.setAccessible(true);
fieldVector.set(AutoJs.getInstance(), vec);
} catch (Exception e) {
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,117 @@
package com.stardust.auojs.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 com.stardust.auojs.inrt.BuildConfig
import com.stardust.auojs.inrt.LogActivity
import com.stardust.auojs.inrt.Pref
import com.stardust.auojs.inrt.autojs.AutoJs
import com.stardust.autojs.execution.ExecutionConfig
import com.stardust.autojs.execution.ScriptExecution
import com.stardust.autojs.project.ProjectConfig
import com.stardust.autojs.script.JavaScriptFileSource
import com.stardust.autojs.script.JavaScriptSource
import com.stardust.autojs.script.ScriptSource
import com.stardust.pio.PFiles
import com.stardust.pio.UncheckedIOException
import com.stardust.util.MD5
import java.io.File
import java.io.IOException
import java.lang.reflect.Field
/**
* 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()
.executePath(mProjectDir)
if (source.executionMode and JavaScriptSource.EXECUTION_MODE_UI != 0) {
config.intentFlags = Intent.FLAG_ACTIVITY_CLEAR_TASK
} 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 (!BuildConfig.DEBUG && 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 = AutoJs::class.java.getDeclaredField("mKey")
fieldKey.isAccessible = true
fieldKey.set(AutoJs.instance, key)
val fieldVector = AutoJs::class.java.getDeclaredField("mInitVector")
fieldVector.isAccessible = true
fieldVector.set(AutoJs.instance, vec)
} catch (e: Exception) {
e.printStackTrace()
}
}
}

View File

@ -1,24 +0,0 @@
package com.stardust.auojs.inrt.launch;
import android.content.Context;
import com.stardust.app.GlobalAppContext;
/**
* Created by Stardust on 2018/3/21.
*/
public class GlobalProjectLauncher extends AssetsProjectLauncher {
private static GlobalProjectLauncher sInstance;
public static GlobalProjectLauncher getInstance() {
if (sInstance == null)
sInstance = new GlobalProjectLauncher(GlobalAppContext.get());
return sInstance;
}
GlobalProjectLauncher(Context context) {
super("project", context);
}
}

View File

@ -0,0 +1,11 @@
package com.stardust.auojs.inrt.launch
import android.annotation.SuppressLint
import com.stardust.app.GlobalAppContext
/**
* Created by Stardust on 2018/3/21.
*/
@SuppressLint("StaticFieldLeak")
object GlobalProjectLauncher: AssetsProjectLauncher("project", GlobalAppContext.get())