6.4.1 - GitHub Actions 支持; 修复屏幕宽高返回数据; 优化构建工具自适应性

This commit is contained in:
SuperMonster003
2023-11-02 10:40:27 +08:00
parent 702522aa81
commit 770d727929
155 changed files with 803 additions and 582 deletions

View File

@@ -415,6 +415,7 @@ open class UiObject(
?: super.findAccessibilityNodeInfosByViewId(viewId)
}
@Deprecated("Deprecated in Java")
override fun recycle() {
try {
super.recycle()

View File

@@ -16,6 +16,7 @@ class ScrollAction(private val mAction: Int, private val mIndex: Int) : SimpleAc
return result
}
@Suppress("DEPRECATION")
private fun recycle(list: List<UiObject>, root: UiObject) {
for (nodeInfo in list) {
if (nodeInfo !== root)
@@ -34,6 +35,7 @@ class ScrollAction(private val mAction: Int, private val mIndex: Int) : SimpleAc
return list
}
@Suppress("DEPRECATION")
private fun findScrollableNodes(node: UiObject?, list: MutableList<UiObject>) {
if (node == null) {
return

View File

@@ -24,6 +24,7 @@ class ScrollMaxAction(private val mScrollAction: Int) : SimpleAction() {
return result
}
@Suppress("DEPRECATION")
private fun reset() {
mMaxScrollableNode?.let {
if(it != mRootNode){

View File

@@ -7,6 +7,7 @@ import kotlin.collections.ArrayList
object BFS : SearchAlgorithm {
@Suppress("DEPRECATION")
override fun search(root: UiObject, filter: Filter, limit: Int): ArrayList<UiObject> {
val result = ArrayList<UiObject>()
val queue = ArrayDeque<UiObject>()

View File

@@ -11,6 +11,7 @@ import kotlin.collections.ArrayList
*/
object DFS : SearchAlgorithm {
@Suppress("DEPRECATION")
override fun search(root: UiObject, filter: Filter, limit: Int): ArrayList<UiObject> {
val result = ArrayList<UiObject>()
val stack = LinkedList<UiObject>()

View File

@@ -55,6 +55,7 @@ class TestUiObject @JvmOverloads constructor(private val mChildCount: Int = max(
return random.nextBoolean()
}
@Deprecated("Deprecated in Java")
override fun recycle() {
if (mRecycled) {
throw IllegalStateException()

View File

@@ -15,6 +15,7 @@ import androidx.appcompat.app.AppCompatActivity;
import org.autojs.autojs.core.eventloop.EventEmitter;
import org.autojs.autojs.core.eventloop.SimpleEvent;
import org.autojs.autojs.core.looper.Loopers;
import org.autojs.autojs.engine.JavaScriptEngine;
import org.autojs.autojs.engine.LoopBasedJavaScriptEngine;
import org.autojs.autojs.engine.ScriptEngine;
@@ -37,8 +38,6 @@ public class ScriptExecuteActivity extends AppCompatActivity {
private ScriptSource mScriptSource;
private ActivityScriptExecution mScriptExecution;
private ScriptRuntime mRuntime;
private EventEmitter mEventEmitter;
public static ActivityScriptExecution execute(Context context, ScriptEngineManager manager, ScriptExecutionTask task) {
@@ -137,14 +136,22 @@ public class ScriptExecuteActivity extends AppCompatActivity {
@Override
protected void onDestroy() {
super.onDestroy();
Log.d(LOG_TAG, "onDestroy");
if (mScriptEngine != null) {
mScriptEngine.put("activity", null);
mScriptEngine.setTag("activity", null);
mScriptEngine.destroy();
}
mScriptExecution = null;
mRuntime.loopers.waitWhenIdle(false);
if (mRuntime != null) {
Loopers loopers = mRuntime.loopers;
if (loopers != null) {
loopers.waitWhenIdle(false);
}
}
}
@Override

View File

@@ -9,7 +9,7 @@ import rikka.shizuku.Shizuku
class ShizukuPermission(override val context: Context) : PermissionItemHelper {
override fun has() = WrappedShizuku.hasPermission()
override fun has() = WrappedShizuku.hasPermission() && WrappedShizuku.isRunning()
override fun request() {
when {
@@ -24,7 +24,7 @@ class ShizukuPermission(override val context: Context) : PermissionItemHelper {
} catch (e: Throwable) {
e.printStackTrace()
}
WrappedShizuku.config(true) ?: ViewUtils.showToast(context, R.string.error_failed_to_grant_shizuku_access)
WrappedShizuku.config(context, true) ?: ViewUtils.showToast(context, R.string.error_failed_to_grant_shizuku_access)
}
}
}
@@ -33,10 +33,8 @@ class ShizukuPermission(override val context: Context) : PermissionItemHelper {
when {
!WrappedShizuku.isInstalled() -> ViewUtils.showToast(context, R.string.error_shizuku_is_not_installed)
Shizuku.isPreV11() -> ViewUtils.showToast(context, R.string.error_shizuku_version_is_not_supported)
else -> WrappedShizuku.config(false) ?: ViewUtils.showToast(context, R.string.error_failed_to_revoke_shizuku_access)
else -> WrappedShizuku.config(context, false) ?: ViewUtils.showToast(context, R.string.error_failed_to_revoke_shizuku_access)
}
}
}

View File

@@ -1,7 +1,6 @@
package org.autojs.autojs.runtime.api
import android.app.Activity
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.pm.ApplicationInfo
@@ -85,7 +84,6 @@ class AppUtils {
null
}
@Suppress("DEPRECATION")
private fun getApplicationInfoCompat(packageManager: PackageManager, packageName: String, flags: Int) = when {
Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU -> {
packageManager.getApplicationInfo(packageName, ApplicationInfoFlags.of(flags.toLong()))
@@ -115,7 +113,6 @@ class AppUtils {
false
}
@Suppress("DEPRECATION")
private fun getPackageInfoCompat(packageManager: PackageManager, packageName: String, flags: Int) = when {
Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU -> {
packageManager.getPackageInfo(packageName, PackageInfoFlags.of(flags.toLong()))
@@ -230,10 +227,10 @@ class AppUtils {
}
@JvmStatic
fun isBroadcastShortForm(s: String) = BroadcastShortForm.values().any { it.shortName.contentEquals(s) }
fun isBroadcastShortForm(s: String) = BroadcastShortForm.entries.any { it.shortName.contentEquals(s) }
@JvmStatic
fun isActivityShortForm(s: String) = ActivityShortForm.values().any { it.shortName.contentEquals(s) }
fun isActivityShortForm(s: String) = ActivityShortForm.entries.any { it.shortName.contentEquals(s) }
fun getInstalledApplications(context: Context): List<ApplicationInfo> = context.packageManager.let {
when {

View File

@@ -250,7 +250,9 @@ public class Events extends EventEmitter implements OnKeyListener, TouchObserver
NotificationListenerService.getInstance().removeListener(this);
}
mListeningNotification = false;
mLoopers.waitWhenIdle(mListeningToast);
if (!mListeningToast) {
mLoopers.waitWhenIdle(false);
}
}
public void observeToast() {
@@ -266,11 +268,10 @@ public class Events extends EventEmitter implements OnKeyListener, TouchObserver
public void removeToastObserver() {
mAccessibilityBridge.getNotificationObserver().removeToastListener(this);
if (NotificationListenerService.getInstance() != null) {
NotificationListenerService.getInstance().removeListener(this);
}
mListeningToast = false;
mLoopers.waitWhenIdle(mListeningNotification);
if (!mListeningNotification) {
mLoopers.waitWhenIdle(false);
}
}
public Events onNotification(Object listener) {
@@ -283,7 +284,6 @@ public class Events extends EventEmitter implements OnKeyListener, TouchObserver
return this;
}
public void recycle() {
broadcast.unregister();
if (mListeningKey) {

View File

@@ -7,7 +7,6 @@ import android.view.ContextThemeWrapper
import android.view.View
import android.view.ViewGroup
import org.autojs.autojs.annotation.ScriptInterface
import org.autojs.autojs.ui.enhancedfloaty.FloatyService
import org.autojs.autojs.core.floaty.BaseResizableFloatyWindow
import org.autojs.autojs.core.floaty.RawWindow
import org.autojs.autojs.core.floaty.RawWindow.RawFloaty
@@ -16,10 +15,11 @@ import org.autojs.autojs.permission.DisplayOverOtherAppsPermission
import org.autojs.autojs.runtime.ScriptRuntime
import org.autojs.autojs.runtime.exception.ScriptInterruptedException
import org.autojs.autojs.tool.UiHandler
import org.autojs.autojs.ui.enhancedfloaty.FloatyService
import org.autojs.autojs.util.ViewUtils.setViewMeasure
import org.autojs.autojs6.R
import java.lang.Exception
import java.util.concurrent.CopyOnWriteArraySet
import kotlin.concurrent.Volatile
/**
* Created by Stardust on 2017/12/5.
@@ -97,62 +97,65 @@ class Floaty(private val mUiHandler: UiHandler, private val mRuntime: ScriptRunt
inner class JsRawWindow(floaty: RawFloaty) : JsWindow {
private var mWindow = RawWindow(floaty, mUiHandler.context)
private var mWindow: RawWindow? = null
private var mExitOnClose = false
init {
mWindow = RawWindow(floaty, mUiHandler.context)
mUiHandler.context.startService(Intent(mUiHandler.context, FloatyService::class.java))
runWithWindow { FloatyService.addWindow(mWindow) }
val r = Runnable { FloatyService.addWindow(mWindow) }
/* 如果是 UI 线程则直接创建, 否则放入 UI 线程. */
if (isUiThread()) r.run() else mUiHandler.post(r)
}
fun findView(id: String?): View? {
return JsViewHelper.findViewByStringId(mWindow.contentView, id)
return mWindow?.let { JsViewHelper.findViewByStringId(it.contentView, id) }
}
val x: Int
get() = mWindow.windowBridge.x
get() = mWindow?.windowBridge?.x ?: -1
val y: Int
get() = mWindow.windowBridge.y
get() = mWindow?.windowBridge?.y ?: -1
val width: Int
get() = mWindow.windowView.width
get() = mWindow?.windowView?.width ?: 0
val height: Int
get() = mWindow.windowView.height
get() = mWindow?.windowView?.height ?: 0
fun setSize(w: Int, h: Int) = runWithWindow {
mWindow.windowBridge.updateMeasure(w, h)
setViewMeasure(mWindow.windowView, w, h)
mWindow!!.windowBridge.updateMeasure(w, h)
setViewMeasure(mWindow!!.windowView, w, h)
}
fun setTouchable(touchable: Boolean) = runWithWindow {
mWindow.setTouchable(touchable)
mWindow!!.setTouchable(touchable)
}
private fun runWithWindow(r: Runnable) {
if (isUiThread()) {
r.run()
} else {
mUiHandler.post(r)
}
mWindow ?: return
mUiHandler.post(r)
}
fun setPosition(x: Int, y: Int) = runWithWindow {
mWindow.windowBridge.updatePosition(x, y)
mWindow!!.windowBridge.updatePosition(x, y)
}
fun exitOnClose() {
mExitOnClose = true
}
fun requestFocus() = mWindow.requestWindowFocus()
fun requestFocus() = mWindow?.requestWindowFocus()
fun disableFocus() = mWindow.disableWindowFocus()
fun disableFocus() = mWindow?.disableWindowFocus()
fun close() = close(true)
override fun close(removeFromWindows: Boolean) {
if (!removeFromWindows || removeWindow(this)) {
runWithWindow {
mWindow.close()
mWindow!!.close()
mWindow = null
if (mExitOnClose) {
mRuntime.exit()
}
@@ -163,71 +166,76 @@ class Floaty(private val mUiHandler: UiHandler, private val mRuntime: ScriptRunt
inner class JsResizableWindow(supplier: BaseResizableFloatyWindow.ViewSupplier) : JsWindow {
private lateinit var mView: View
private var mView: View? = null
@Volatile
private var mWindow = BaseResizableFloatyWindow(mUiHandler.context, object : BaseResizableFloatyWindow.ViewSupplier {
override fun inflate(context: Context?, parent: ViewGroup?): View {
return supplier.inflate(context, parent).also { mView = it }
}
})
private var mWindow: BaseResizableFloatyWindow? = null
private var mExitOnClose = false
init {
mWindow = BaseResizableFloatyWindow(mContext, object : BaseResizableFloatyWindow.ViewSupplier {
override fun inflate(context: Context?, parent: ViewGroup?): View {
return supplier.inflate(context, parent).also { mView = it }
}
})
mUiHandler.context.startService(Intent(mUiHandler.context, FloatyService::class.java))
runWithWindow { FloatyService.addWindow(mWindow) }
mWindow.setOnCloseButtonClickListener { _ -> close() }
val r = Runnable { FloatyService.addWindow(mWindow!!) }
/* 如果是 UI 线程则直接创建, 否则放入 UI 线程. */
if (Looper.myLooper() == Looper.getMainLooper()) r.run() else mUiHandler.post(r)
mWindow!!.setOnCloseButtonClickListener { _ -> close() }
// setSize(mWindow.getWindowBridge().getScreenWidth() / 2, mWindow.getWindowBridge().getScreenHeight() / 2);
}
fun findView(id: String?) = JsViewHelper.findViewByStringId(mView, id)
fun findView(id: String?) = mView?.let { JsViewHelper.findViewByStringId(it, id) }
val x: Int
get() = mWindow.windowBridge.x
get() = mWindow?.windowBridge?.x ?: -1
val y: Int
get() = mWindow.windowBridge.y
get() = mWindow?.windowBridge?.y ?: -1
val width: Int
get() = mWindow.rootView.width
get() = mWindow?.rootView?.width ?: 0
val height: Int
get() = mWindow.rootView.height
get() = mWindow?.rootView?.height ?: 0
fun setSize(w: Int, h: Int) = runWithWindow {
mWindow.windowBridge.updateMeasure(w, h)
setViewMeasure(mWindow.rootView, w, h)
mWindow!!.windowBridge.updateMeasure(w, h)
setViewMeasure(mWindow!!.rootView, w, h)
}
private fun runWithWindow(r: Runnable) {
if (isUiThread()) {
r.run()
} else {
mUiHandler.post(r)
}
mWindow ?: return
mUiHandler.post(r)
}
fun setPosition(x: Int, y: Int) = runWithWindow {
mWindow.windowBridge.updatePosition(x, y)
mWindow!!.windowBridge.updatePosition(x, y)
}
var isAdjustEnabled: Boolean
get() = mWindow.isAdjustEnabled
get() = mWindow?.isAdjustEnabled ?: false
set(enabled) {
runWithWindow { mWindow.isAdjustEnabled = enabled }
runWithWindow { mWindow!!.isAdjustEnabled = enabled }
}
fun exitOnClose() {
mExitOnClose = true
}
fun requestFocus() = mWindow.requestWindowFocus()
fun requestFocus() = mWindow?.requestWindowFocus()
fun disableFocus() = mWindow.disableWindowFocus()
fun disableFocus() = mWindow?.disableWindowFocus()
fun close() = close(true)
override fun close(removeFromWindows: Boolean) {
if (!removeFromWindows || removeWindow(this)) {
runWithWindow {
mWindow.close()
mWindow!!.close()
mWindow = null
if (mExitOnClose) {
mRuntime.exit()
}

View File

@@ -1,6 +1,7 @@
package org.autojs.autojs.runtime.api
import android.app.Activity
import android.content.Context
import android.content.res.Configuration.ORIENTATION_LANDSCAPE
import android.content.res.Configuration.ORIENTATION_PORTRAIT
import android.content.res.Resources
@@ -8,6 +9,7 @@ import android.graphics.Point
import android.util.DisplayMetrics
import android.view.Surface.ROTATION_0
import android.view.WindowManager
import org.autojs.autojs.app.GlobalAppContext
/**
* Created by Stardust on 2017/4/26.
@@ -50,13 +52,19 @@ class ScreenMetrics(private var designWidth: Int, private var designHeight: Int)
var resources: Resources? = null
private var mWindowManager: WindowManager? = null
private var mIsInitialized = false
private var mPrivateWindowManager: WindowManager? = null
private var windowManager: WindowManager
get() = mPrivateWindowManager ?: GlobalAppContext.get().getSystemService(Context.WINDOW_SERVICE) as WindowManager
set(value) {
mPrivateWindowManager = value
}
@Suppress("DEPRECATION")
@JvmStatic
val rotation: Int
get() = mWindowManager?.defaultDisplay?.rotation ?: ROTATION_0
get() = windowManager.defaultDisplay?.rotation ?: ROTATION_0
@JvmStatic
val orientation: Int
@@ -74,30 +82,24 @@ class ScreenMetrics(private var designWidth: Int, private var designHeight: Int)
@Suppress("DEPRECATION")
val deviceScreenWidth: Int
get() {
resources?.displayMetrics?.widthPixels?.takeIf { it > 0 }?.let { return it }
// resources?.displayMetrics?.widthPixels?.takeIf { it > 0 }?.let { return it }
val metricsLegacy = DisplayMetrics()
val display = mWindowManager?.defaultDisplay?.apply { getRealMetrics(metricsLegacy) }
metricsLegacy.widthPixels.takeIf { it > 0 }?.let { return it }
display?.width?.takeIf { it > 0 }?.let { return it }
return 0
return windowManager.defaultDisplay.apply { getRealMetrics(metricsLegacy) }.let { display ->
maxOf(metricsLegacy.widthPixels, display.width, 0)
}
}
@JvmStatic
@Suppress("DEPRECATION")
val deviceScreenHeight: Int
get() {
resources?.displayMetrics?.heightPixels?.takeIf { it > 0 }?.let { return it }
// resources?.displayMetrics?.heightPixels?.takeIf { it > 0 }?.let { return it }
val metricsLegacy = DisplayMetrics()
val display = mWindowManager?.defaultDisplay?.apply { getRealMetrics(metricsLegacy) }
metricsLegacy.heightPixels.takeIf { it > 0 }?.let { return it }
display?.height?.takeIf { it > 0 }?.let { return it }
return 0
return windowManager.defaultDisplay.apply { getRealMetrics(metricsLegacy) }.let { display ->
maxOf(metricsLegacy.heightPixels, display.height, 0)
}
}
@JvmStatic
@@ -105,14 +107,14 @@ class ScreenMetrics(private var designWidth: Int, private var designHeight: Int)
val deviceScreenDensity: Int
get() {
val metricsLegacy = DisplayMetrics()
mWindowManager?.defaultDisplay?.apply { getRealMetrics(metricsLegacy) }
windowManager.defaultDisplay?.apply { getRealMetrics(metricsLegacy) }
return metricsLegacy.densityDpi
}
@JvmStatic
fun init(activity: Activity) {
resources = activity.resources
mWindowManager = activity.windowManager
windowManager = activity.windowManager
mIsInitialized = true
}

View File

@@ -1,6 +1,7 @@
package org.autojs.autojs.runtime.api
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.ServiceConnection
import android.content.pm.PackageManager
@@ -11,6 +12,7 @@ import org.autojs.autojs.annotation.ScriptInterface
import org.autojs.autojs.app.GlobalAppContext
import org.autojs.autojs.core.shizuku.IUserService
import org.autojs.autojs.core.shizuku.UserService
import org.autojs.autojs.util.App.*
import org.autojs.autojs.util.ViewUtils
import org.autojs.autojs6.BuildConfig
import org.autojs.autojs6.R
@@ -27,10 +29,8 @@ object WrappedShizuku {
private val TAG: String = WrappedShizuku::class.java.simpleName
private val context
get() = GlobalAppContext.get()
private val mRequestCode = "shizuku-request-code".hashCode()
private var mHasBinder = false
private val mUserServiceConnection: ServiceConnection = object : ServiceConnection {
override fun onServiceConnected(componentName: ComponentName, binder: IBinder?) {
@@ -58,11 +58,13 @@ object WrappedShizuku {
Log.d(TAG, "Shizuku pre-v11 is not supported")
} else {
Log.d(TAG, "Binder received")
mHasBinder = true
}
}
private val mBinderDeadListener = Shizuku.OnBinderDeadListener {
Log.d(TAG, "Binder dead")
mHasBinder = false
}
private val mRequestPermissionResultListener: (requestCode: Int, grantResult: Int) -> Unit = { requestCode: Int, grantResult: Int ->
@@ -114,12 +116,15 @@ object WrappedShizuku {
false.also { e.printStackTrace() }
}
@ScriptInterface
fun isRunning() = mHasBinder
@ScriptInterface
fun requestPermission() = Shizuku.requestPermission(mRequestCode)
@ScriptInterface
@JvmOverloads
fun config(isRequest: Boolean? = null): Intent? {
fun config(context: Context = GlobalAppContext.get(), isRequest: Boolean? = null): Intent? {
return getLaunchIntent()?.also {
context.startActivity(it)
val message = when (isRequest) {
@@ -131,6 +136,9 @@ object WrappedShizuku {
}
}
@ScriptInterface
fun config(isRequest: Boolean) = config(GlobalAppContext.get(), isRequest)
@ScriptInterface
fun execCommand(cmd: String): ShellResult {
ensureService()
@@ -139,7 +147,11 @@ object WrappedShizuku {
} catch (e: Throwable) {
ShellResult().apply {
code = 1
error = e.message ?: ""
error = e.message ?: when {
!hasPermission() -> "No permission to access Shizuku"
!isRunning() -> "Shizuku service may be not running"
else -> ""
}
result = ""
}.also { e.printStackTrace() }
}
@@ -151,7 +163,8 @@ object WrappedShizuku {
}
@ScriptInterface
fun ensureService() {
@JvmOverloads
fun ensureService(context: Context = GlobalAppContext.get()) {
service ?: throw IllegalStateException(context.getString(R.string.error_unable_to_use_shizuku_service))
}
@@ -163,7 +176,7 @@ object WrappedShizuku {
}
private fun getLaunchIntent(): Intent? {
return context.packageManager.getLaunchIntentForPackage(org.autojs.autojs.util.App.SHIZUKU.packageName)?.apply {
return GlobalAppContext.get().packageManager.getLaunchIntentForPackage(SHIZUKU.packageName)?.apply {
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
}
}

View File

@@ -1,5 +1,6 @@
package org.autojs.autojs.ui.doc
import android.annotation.SuppressLint
import android.os.Bundle
import android.webkit.WebView
import org.autojs.autojs.ui.BaseActivity
@@ -28,6 +29,7 @@ class DocumentationActivity : BaseActivity() {
}
}
@SuppressLint("MissingSuperCall")
@Suppress("OVERRIDE_DEPRECATION")
override fun onBackPressed() {
if (mWebView.canGoBack()) {

View File

@@ -184,6 +184,7 @@ open class EditActivity : BaseActivity(), DelegateHost, PermissionRequestProxyAc
return mMediator
}
@Deprecated("Deprecated in Java")
@SuppressLint("MissingSuperCall")
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
mMediator.onActivityResult(requestCode, resultCode, data)

View File

@@ -207,7 +207,7 @@ class CodeEditText : AppCompatEditText {
mMatchingBrackets[0], mMatchingBrackets[1] -> mTheme.getColorForToken(TokenMapping.TOKEN_MATCHED_BRACKET)
else -> highlightTokens.colors[previousColorPos]
}
var i = visibleCharStart
var i = previousColorPos
while (i < visibleCharEnd) {
val color = when (i) {
mUnmatchedBracket -> mTheme.getColorForToken(Token.ERROR)

View File

@@ -117,8 +117,10 @@ class CodeEditor : HVScrollView {
private val selectionText: String
get() {
val s = codeEditText.selectionStart
val e = codeEditText.selectionEnd
val sRaw = codeEditText.selectionStart
val eRaw = codeEditText.selectionEnd
val s = minOf(sRaw, eRaw)
val e = maxOf(sRaw, eRaw)
return if (s == e) "" else codeEditText.text?.substring(s, e) ?: ""
}
@@ -181,7 +183,7 @@ class CodeEditor : HVScrollView {
fun copyLine() {
val layout = codeEditText.layout
val line = LayoutHelper.getLineOfChar(layout, codeEditText.selectionStart)
val line = LayoutHelper.getLineOfChar(layout, minOf(codeEditText.selectionStart, codeEditText.selectionEnd))
if (line >= 0 && line < layout.lineCount) {
val text = codeEditText.text
var lineText: CharSequence? = null
@@ -195,8 +197,10 @@ class CodeEditor : HVScrollView {
private fun getCoveredLinesText(): CharSequence {
val layout = codeEditText.layout
val lineStart = LayoutHelper.getLineOfChar(layout, codeEditText.selectionStart)
val lineEnd = LayoutHelper.getLineOfChar(layout, codeEditText.selectionEnd)
val lineStartRaw = LayoutHelper.getLineOfChar(layout, codeEditText.selectionStart)
val lineEndRaw = LayoutHelper.getLineOfChar(layout, codeEditText.selectionEnd)
val lineStart = minOf(lineStartRaw, lineEndRaw)
val lineEnd = maxOf(lineStartRaw, lineEndRaw)
if (lineStart >= 0 && lineStart < layout.lineCount) {
if (lineEnd >= 0 && lineEnd < layout.lineCount) {
return text.subSequence(layout.getLineStart(lineStart), layout.getLineEnd(lineEnd))
@@ -208,8 +212,10 @@ class CodeEditor : HVScrollView {
private fun replaceSelectedLines(feature: Regex, transform: (MatchResult) -> CharSequence) {
val text = codeEditText.text ?: return
val layout = codeEditText.layout
val lineStart = LayoutHelper.getLineOfChar(layout, codeEditText.selectionStart)
val lineEnd = LayoutHelper.getLineOfChar(layout, codeEditText.selectionEnd)
val lineStartRaw = LayoutHelper.getLineOfChar(layout, codeEditText.selectionStart)
val lineEndRaw = LayoutHelper.getLineOfChar(layout, codeEditText.selectionEnd)
val lineStart = minOf(lineStartRaw, lineEndRaw)
val lineEnd = maxOf(lineStartRaw, lineEndRaw)
val newText = getCoveredLinesText().split("\n").joinToString("\n") { it.replace(feature, transform) }
text.replace(layout.getLineStart(lineStart), layout.getLineEnd(lineEnd), newText)
}
@@ -217,7 +223,7 @@ class CodeEditor : HVScrollView {
fun deleteLine() {
val text = codeEditText.text ?: return
val layout = codeEditText.layout
val line = LayoutHelper.getLineOfChar(layout, codeEditText.selectionStart)
val line = LayoutHelper.getLineOfChar(layout, minOf(codeEditText.selectionStart, codeEditText.selectionEnd))
if (line >= 0 && line < layout.lineCount) {
text.replace(layout.getLineStart(line), layout.getLineEnd(line), "")
}
@@ -236,7 +242,7 @@ class CodeEditor : HVScrollView {
fun jumpToLineStart() {
val layout = codeEditText.layout
val line = LayoutHelper.getLineOfChar(layout, codeEditText.selectionStart)
val line = LayoutHelper.getLineOfChar(layout, minOf(codeEditText.selectionStart, codeEditText.selectionEnd))
if (line >= 0 && line < layout.lineCount) {
codeEditText.setSelection(layout.getLineStart(line))
}
@@ -244,7 +250,7 @@ class CodeEditor : HVScrollView {
fun jumpToLineEnd() {
val layout = codeEditText.layout
val line = LayoutHelper.getLineOfChar(layout, codeEditText.selectionStart)
val line = LayoutHelper.getLineOfChar(layout, minOf(codeEditText.selectionStart, codeEditText.selectionEnd))
if (line >= 0 && line < layout.lineCount) {
codeEditText.setSelection(layout.getLineEnd(line) - 1)
}
@@ -414,12 +420,16 @@ class CodeEditor : HVScrollView {
}
fun replaceSelection() {
codeEditText.text?.replace(codeEditText.selectionStart, codeEditText.selectionEnd, mReplacement)
val selectionStartRaw = codeEditText.selectionStart
val selectionEndRaw = codeEditText.selectionEnd
val selectionStart = minOf(selectionStartRaw, selectionEndRaw)
val selectionEnd = maxOf(selectionStartRaw, selectionEndRaw)
codeEditText.text?.replace(selectionStart, selectionEnd, mReplacement)
}
fun beautifyCode() {
setProgress(true)
val pos = codeEditText.selectionStart
val pos = minOf(codeEditText.selectionStart, codeEditText.selectionEnd)
mJsBeautifier.beautify(codeEditText.text.toString(), object : JsBeautifier.Callback {
override fun onSuccess(beautifiedCode: String) {
codeEditText.setText(beautifiedCode)
@@ -439,7 +449,7 @@ class CodeEditor : HVScrollView {
}
fun insert(insertText: String?) {
val selection = codeEditText.selectionStart.coerceAtLeast(0)
val selection = minOf(codeEditText.selectionStart, codeEditText.selectionEnd).coerceAtLeast(0)
codeEditText.text!!.insert(selection, insertText)
}
@@ -449,7 +459,7 @@ class CodeEditor : HVScrollView {
}
fun moveCursor(dCh: Int) {
codeEditText.setSelection(codeEditText.selectionStart + dCh)
codeEditText.setSelection(minOf(codeEditText.selectionStart, codeEditText.selectionEnd) + dCh)
}
fun markTextAsSaved() {
@@ -472,7 +482,7 @@ class CodeEditor : HVScrollView {
fun addOrRemoveBreakpointAtCurrentLine() {
val layout = codeEditText.layout
val line = LayoutHelper.getLineOfChar(layout, codeEditText.selectionStart)
val line = LayoutHelper.getLineOfChar(layout, minOf(codeEditText.selectionStart, codeEditText.selectionEnd))
if (line >= 0 && line < layout.lineCount) {
addOrRemoveBreakpoint(line)
}

View File

@@ -318,8 +318,13 @@ public class HVScrollView extends FrameLayout {
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
// Let the focused view and/or our descendants get the key first
return super.dispatchKeyEvent(event) || executeKeyEvent(event);
try {
// Let the focused view and/or our descendants get the key first
return super.dispatchKeyEvent(event) || executeKeyEvent(event);
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
@@ -395,15 +400,15 @@ public class HVScrollView extends FrameLayout {
public boolean onInterceptTouchEvent(MotionEvent ev) {
/*
* This method JUST determines whether we want to intercept the motion.
* If we return true, onMotionEvent will be called and we do the actual
* scrolling there.
*/
* If we return true, onMotionEvent will be called and we do the actual
* scrolling there.
*/
/*
* Shortcut the most recurring case: the user is in the dragging
* state and he is moving his finger. We want to intercept this
* motion.
*/
/*
* Shortcut the most recurring case: the user is in the dragging
* state and he is moving his finger. We want to intercept this
* motion.
*/
final int action = ev.getAction();
if ((action == MotionEvent.ACTION_MOVE) && (mIsBeingDragged)) {
return true;
@@ -471,10 +476,10 @@ public class HVScrollView extends FrameLayout {
case MotionEvent.ACTION_POINTER_UP -> onSecondaryPointerUp(ev);
}
/*
* The only time we want to intercept motion events is if we are in the
* drag mode.
*/
/*
* The only time we want to intercept motion events is if we are in the
* drag mode.
*/
return mIsBeingDragged;
}
@@ -502,10 +507,10 @@ public class HVScrollView extends FrameLayout {
return false;
}
/*
* If being flinged and user touches, stop the fling. isFinished
* will be false if being flinged.
*/
/*
* If being flinged and user touches, stop the fling. isFinished
* will be false if being flinged.
*/
if (!mScroller.isFinished()) {
mScroller.abortAnimation();
}
@@ -612,13 +617,13 @@ public class HVScrollView extends FrameLayout {
List<View> focusables = getFocusables(View.FOCUS_FORWARD);
View focusCandidate = null;
/*
* A fully contained focusable is one where its top is below the bound's
* top, and its bottom is above the bound's bottom. A partially
* contained focusable is one where some part of it is within the
* bounds, but it also has some part that is not within bounds. A fully contained
* focusable is preferred to a partially contained focusable.
*/
/*
* A fully contained focusable is one where its top is below the bound's
* top, and its bottom is above the bound's bottom. A partially
* contained focusable is one where some part of it is within the
* bounds, but it also has some part that is not within bounds. A fully contained
* focusable is preferred to a partially contained focusable.
*/
boolean foundFullyContainedFocusable = false;
int count = focusables.size();
@@ -628,16 +633,16 @@ public class HVScrollView extends FrameLayout {
int viewBottom = view.getBottom();
if (top < viewBottom && viewTop < bottom) {
/*
* the focusable is in the target area, it is a candidate for
* focusing
*/
/*
* the focusable is in the target area, it is a candidate for
* focusing
*/
final boolean viewIsFullyContained = (top < viewTop) &&
(viewBottom < bottom);
if (focusCandidate == null) {
/* No candidate, take this one */
/* No candidate, take this one */
focusCandidate = view;
foundFullyContainedFocusable = viewIsFullyContained;
} else {
@@ -648,23 +653,23 @@ public class HVScrollView extends FrameLayout {
if (foundFullyContainedFocusable) {
if (viewIsFullyContained && viewIsCloserToBoundary) {
/*
* We're dealing with only fully contained views, so
* it has to be closer to the boundary to beat our
* candidate
*/
/*
* We're dealing with only fully contained views, so
* it has to be closer to the boundary to beat our
* candidate
*/
focusCandidate = view;
}
} else {
if (viewIsFullyContained) {
/* Any fully contained view beats a partially contained view */
/* Any fully contained view beats a partially contained view */
focusCandidate = view;
foundFullyContainedFocusable = true;
} else if (viewIsCloserToBoundary) {
/*
* Partially contained view beats another partially
* contained view if it's closer
*/
/*
* Partially contained view beats another partially
* contained view if it's closer
*/
focusCandidate = view;
}
}
@@ -680,13 +685,13 @@ public class HVScrollView extends FrameLayout {
List<View> focusables = getFocusables(View.FOCUS_FORWARD);
View focusCandidate = null;
/*
* A fully contained focusable is one where its left is below the bound's
* left, and its right is above the bound's right. A partially
* contained focusable is one where some part of it is within the
* bounds, but it also has some part that is not within bounds. A fully contained
* focusable is preferred to a partially contained focusable.
*/
/*
* A fully contained focusable is one where its left is below the bound's
* left, and its right is above the bound's right. A partially
* contained focusable is one where some part of it is within the
* bounds, but it also has some part that is not within bounds. A fully contained
* focusable is preferred to a partially contained focusable.
*/
boolean foundFullyContainedFocusable = false;
int count = focusables.size();
@@ -696,16 +701,16 @@ public class HVScrollView extends FrameLayout {
int viewRight = view.getRight();
if (left < viewRight && viewLeft < right) {
/*
* the focusable is in the target area, it is a candidate for
* focusing
*/
/*
* the focusable is in the target area, it is a candidate for
* focusing
*/
final boolean viewIsFullyContained = (left < viewLeft) &&
(viewRight < right);
if (focusCandidate == null) {
/* No candidate, take this one */
/* No candidate, take this one */
focusCandidate = view;
foundFullyContainedFocusable = viewIsFullyContained;
} else {
@@ -715,23 +720,23 @@ public class HVScrollView extends FrameLayout {
if (foundFullyContainedFocusable) {
if (viewIsFullyContained && viewIsCloserToBoundary) {
/*
* We're dealing with only fully contained views, so
* it has to be closer to the boundary to beat our
* candidate
*/
/*
* We're dealing with only fully contained views, so
* it has to be closer to the boundary to beat our
* candidate
*/
focusCandidate = view;
}
} else {
if (viewIsFullyContained) {
/* Any fully contained view beats a partially contained view */
/* Any fully contained view beats a partially contained view */
focusCandidate = view;
foundFullyContainedFocusable = true;
} else if (viewIsCloserToBoundary) {
/*
* Partially contained view beats another partially
* contained view if it's closer
*/
/*
* Partially contained view beats another partially
* contained view if it's closer
*/
focusCandidate = view;
}
}
@@ -1180,7 +1185,7 @@ public class HVScrollView extends FrameLayout {
private void scrollToChild(View child) {
child.getDrawingRect(mTempRect);
/* Offset from child's local coordinates to ScrollView coordinates */
/* Offset from child's local coordinates to ScrollView coordinates */
offsetDescendantRectToMyCoords(child, mTempRect);
int scrollDeltaV = computeScrollDeltaToGetChildRectOnScreenV(mTempRect);
@@ -1513,29 +1518,29 @@ public class HVScrollView extends FrameLayout {
private int clamp(int n, int my, int child) {
if (my >= child || n < 0) {
/* my >= child is this case:
* |--------------- me ---------------|
* |------ child ------|
* or
* |--------------- me ---------------|
* |------ child ------|
* or
* |--------------- me ---------------|
* |------ child ------|
*
* n < 0 is this case:
* |------ me ------|
* |-------- child --------|
* |-- mScrollX --|
*/
/* my >= child is this case:
* |--------------- me ---------------|
* |------ child ------|
* or
* |--------------- me ---------------|
* |------ child ------|
* or
* |--------------- me ---------------|
* |------ child ------|
*
* n < 0 is this case:
* |------ me ------|
* |-------- child --------|
* |-- mScrollX --|
*/
return 0;
}
if ((my + n) > child) {
/* this case:
* |------ me ------|
* |------ child ------|
* |-- mScrollX --|
*/
/* this case:
* |------ me ------|
* |------ child ------|
* |-- mScrollX --|
*/
return child - my;
}
return n;

View File

@@ -19,11 +19,19 @@ public class FloatyService extends Service {
private static final CopyOnWriteArraySet<FloatyWindow> windows = new CopyOnWriteArraySet<>();
private static FloatyService instance;
private WindowManager windowManager;
public Size initialSize;
public FloatyService() {
/* Empty constructor. */
}
public static void addWindow(FloatyWindow window) {
if (windows.add(window) && instance != null) {
window.onCreate(instance, instance.mWindowManager);
window.onCreate(instance, instance.windowManager);
}
}
@@ -31,15 +39,12 @@ public class FloatyService extends Service {
windows.remove(window);
}
private static FloatyService instance;
private WindowManager mWindowManager;
@Override
public void onCreate() {
super.onCreate();
mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
for (FloatyWindow delegate : windows) {
delegate.onCreate(this, mWindowManager);
delegate.onCreate(this, windowManager);
}
instance = this;
}

View File

@@ -39,7 +39,7 @@ public abstract class FloatyWindow {
onViewCreated(getWindowView());
//attach to window
attachToWindow(getWindowView(), getWindowManager());
attachToWindow(getWindowView(), manager);
}
protected void onViewCreated(View view) {

View File

@@ -6,7 +6,6 @@ import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.CheckBox
import android.widget.TextView
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
@@ -152,7 +151,8 @@ class NodeInfoView : RecyclerView {
"indexInParent", "childCount", "depth",
// Regular
"checked", "enabled", "editable", "focusable", "selected", "dismissable",
"checked", "enabled", "editable", "focusable",
"selected", "dismissable", "visibleToUser",
// Rare
"contextClickable", "accessibilityFocused",

View File

@@ -27,6 +27,7 @@ import org.autojs.autojs.external.fileprovider.AppFileProvider;
import org.autojs.autojs.model.script.ScriptFile;
import org.autojs.autojs.pref.Language;
import org.autojs.autojs.project.ProjectConfig;
import org.autojs.autojs.runtime.ScriptRuntime;
import org.autojs.autojs.ui.BaseActivity;
import org.autojs.autojs.ui.filechooser.FileChooserDialogBuilder;
import org.autojs.autojs.ui.shortcut.AppsIconSelectActivity;
@@ -77,6 +78,7 @@ public class BuildActivity extends BaseActivity implements ApkBuilder.ProgressCa
private MaterialDialog mProgressDialog;
private String mSource;
private boolean mIsDefaultIcon = true;
private boolean mIsProjectLevelBuilding;
@SuppressLint("SetTextI18n")
@Override
@@ -214,6 +216,7 @@ public class BuildActivity extends BaseActivity implements ApkBuilder.ProgressCa
if (mProjectConfig == null) {
return;
}
mIsProjectLevelBuilding = true;
mOutputPath.setText(new File(mSource, mProjectConfig.getBuildDir()).getPath());
mAppConfig.setVisibility(View.GONE);
mSourcePathContainer.setVisibility(View.GONE);
@@ -242,16 +245,19 @@ public class BuildActivity extends BaseActivity implements ApkBuilder.ProgressCa
return;
}
if (!checkInputs()) {
ViewUtils.showToast(this, getString(R.string.error_input_fields_check_failed));
return;
}
doBuildingApk();
}
private boolean checkInputs() {
if (mIsProjectLevelBuilding) {
return checkNotEmpty(mOutputPath);
}
return checkNotEmpty(mSourcePath)
& checkNotEmpty(mOutputPath)
& checkNotEmpty(mAppName)
& checkNotEmpty(mSourcePath)
& checkNotEmpty(mVersionCode)
& checkNotEmpty(mVersionName)
& checkPackageNameValid(mPackageName);
@@ -269,7 +275,6 @@ public class BuildActivity extends BaseActivity implements ApkBuilder.ProgressCa
return false;
}
return true;
}
private boolean checkNotEmpty(EditText editText) {
@@ -344,6 +349,7 @@ public class BuildActivity extends BaseActivity implements ApkBuilder.ProgressCa
}
String message = getString(R.string.text_failed_to_build) + "\n" + error.getMessage();
ViewUtils.showToast(this, message, true);
ScriptRuntime.popException(message);
Log.e(LOG_TAG, "Failed to build", error);
}
@@ -357,7 +363,6 @@ public class BuildActivity extends BaseActivity implements ApkBuilder.ProgressCa
.negativeText(R.string.text_cancel)
.onPositive((dialog, which) -> IntentUtils.installApkOrToast(BuildActivity.this, outApk.getPath(), AppFileProvider.AUTHORITY))
.show();
}
@Override

View File

@@ -214,6 +214,7 @@ class ProjectConfigActivity : BaseActivity() {
return false
}
@Deprecated("Deprecated in Java")
@SuppressLint("CheckResult", "MissingSuperCall")
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (resultCode != RESULT_OK) {

View File

@@ -311,7 +311,6 @@ class TimedTaskSettingActivity : BaseActivity() {
Log.d(LOG_TAG, "result code = $requestCode")
createOrUpdateTask()
}
@Suppress("DEPRECATION")
super.onActivityResult(requestCode, resultCode, data)
}