diff --git a/.github/workflows/android-test.yml b/.github/workflows/android-test.yml index d5832ef99..d7e477f8d 100644 --- a/.github/workflows/android-test.yml +++ b/.github/workflows/android-test.yml @@ -22,10 +22,8 @@ jobs: java-version: 17 - name: Setup Gradle uses: gradle/gradle-build-action@v2 - - name: set up kotlin - uses: fwilhe2/setup-kotlin@main - with: - version: 1.6.20 + - name: Setup Android SDK + uses: android-actions/setup-android@v3 - name: Build with Gradle run: | chmod 777 ./gradlew @@ -33,5 +31,5 @@ jobs: ./gradlew :app:assembleRelease - uses: actions/upload-artifact@v3 with: - name: apks + name: apks(no signing) path: app/build/outputs/apk/v6/release/* \ No newline at end of file diff --git a/.github/workflows/android.yml b/.github/workflows/android.yml index c3bce4b6e..6fcadb1f0 100644 --- a/.github/workflows/android.yml +++ b/.github/workflows/android.yml @@ -21,6 +21,8 @@ jobs: with: distribution: temurin java-version: 17 + - name: Setup Android SDK + uses: android-actions/setup-android@v3 - name: Setup Gradle uses: gradle/gradle-build-action@v2 @@ -41,8 +43,8 @@ jobs: alias: ${{ secrets.AALIAS }} keyStorePassword: ${{ secrets.AKEY_STORE_PASSWORD }} keyPassword: ${{ secrets.AKEY_PASSWORD }} - env: - BUILD_TOOLS_VERSION: "33.0.0" + env: + BUILD_TOOLS_VERSION: "34.0.0" - name: rename apk run: | cd build/app/signed diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 702f87cb1..a315fb310 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -2,6 +2,13 @@ + + + @@ -440,7 +447,7 @@ android:theme="@style/EditorTheme" /> WebView) { onDismissRequest = { expanded = false }) { DropdownMenuItem(onClick = { dismissMenu() - getWebView().loadUrl(DocumentSource.DOC_V1.uri) + loadHomeDocument(getWebView()) }) { Icon(Icons.Default.Home, contentDescription = null) Text(text = "回到主页") diff --git a/app/src/main/java/org/autojs/autojs/ui/main/drawer/DrawerPage.kt b/app/src/main/java/org/autojs/autojs/ui/main/drawer/DrawerPage.kt index bcf695234..9b9dfad68 100644 --- a/app/src/main/java/org/autojs/autojs/ui/main/drawer/DrawerPage.kt +++ b/app/src/main/java/org/autojs/autojs/ui/main/drawer/DrawerPage.kt @@ -59,7 +59,7 @@ import org.autojs.autojs.ui.compose.widget.MyAlertDialog1 import org.autojs.autojs.ui.compose.widget.MyIcon import org.autojs.autojs.ui.compose.widget.MySwitch import org.autojs.autojs.ui.floating.FloatyWindowManger -import org.autojs.autojs.ui.settings.SettingsActivity_ +import org.autojs.autojs.ui.settings.SettingsActivity import org.autojs.autoxjs.R import org.joda.time.DateTimeZone import org.joda.time.Instant @@ -272,7 +272,7 @@ private fun BottomButtons() { context.startActivity( Intent( context, - SettingsActivity_::class.java + SettingsActivity::class.java ) ) }, diff --git a/app/src/main/java/org/autojs/autojs/ui/main/web/EditorAppManager.kt b/app/src/main/java/org/autojs/autojs/ui/main/web/EditorAppManager.kt index 5c6d86146..9e3a5bd5b 100644 --- a/app/src/main/java/org/autojs/autojs/ui/main/web/EditorAppManager.kt +++ b/app/src/main/java/org/autojs/autojs/ui/main/web/EditorAppManager.kt @@ -23,16 +23,8 @@ class EditorAppManager : Fragment() { container: ViewGroup?, savedInstanceState: Bundle? ): View { - val saveStatus = getSaveStatus(requireContext()) - val name = saveStatus.getString(DocumentSourceKEY, DocumentSource.DOC_V1_LOCAL.name) return swipeRefreshWebView.apply { - switchDocument( - webView, try { - DocumentSource.valueOf(name!!) - } catch (e: Exception) { - DocumentSource.DOC_V1_LOCAL - } - ) + loadHomeDocument(this.webView) fillMaxSize() } } @@ -51,6 +43,18 @@ class EditorAppManager : Fragment() { return saveStatus!! } + fun loadHomeDocument(webView: WebView) { + val saveStatus = getSaveStatus(webView.context) + val name = saveStatus.getString(DocumentSourceKEY, DocumentSource.DOC_V1_LOCAL.name) + switchDocument( + webView, try { + DocumentSource.valueOf(name!!) + } catch (e: Exception) { + DocumentSource.DOC_V1_LOCAL + } + ) + } + fun switchDocument(webView: WebView, documentSource: DocumentSource) { if (documentSource.isLocal) { webView.webViewClient = WebViewClient(webView.context, documentSource.uri) diff --git a/app/src/main/java/org/autojs/autojs/ui/settings/SettingsActivity.java b/app/src/main/java/org/autojs/autojs/ui/settings/SettingsActivity.java deleted file mode 100644 index 58b3d512b..000000000 --- a/app/src/main/java/org/autojs/autojs/ui/settings/SettingsActivity.java +++ /dev/null @@ -1,164 +0,0 @@ -package org.autojs.autojs.ui.settings; - -import android.content.Context; -import android.content.Intent; -import android.os.Bundle; - -import androidx.appcompat.widget.Toolbar; -import androidx.core.util.Pair; -import androidx.fragment.app.DialogFragment; -import androidx.preference.Preference; -import androidx.preference.PreferenceFragmentCompat; - -import com.stardust.pio.PFiles; -import com.stardust.theme.app.ColorSelectActivity; -import com.stardust.theme.util.ListBuilder; -import com.stardust.util.MapBuilder; - -import org.androidannotations.annotations.AfterViews; -import org.androidannotations.annotations.EActivity; -import org.autojs.autoxjs.R; -import org.autojs.autojs.ui.BaseActivity; -import org.autojs.autojs.ui.widget.CommonMarkdownView; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -import de.psdev.licensesdialog.LicenseResolver; -import de.psdev.licensesdialog.LicensesDialog; -import de.psdev.licensesdialog.licenses.License; - -/** - * Created by Stardust on 2017/2/2. - * update by aaron 2022年1月16日 - */ -@EActivity(R.layout.activity_settings) -public class SettingsActivity extends BaseActivity { - - static { - LicenseInfo.INSTANCE.install(); - } - private static final List> COLOR_ITEMS = new ListBuilder>() - .add(new Pair<>(R.color.theme_color_red, R.string.theme_color_red)) - .add(new Pair<>(R.color.theme_color_pink, R.string.theme_color_pink)) - .add(new Pair<>(R.color.theme_color_purple, R.string.theme_color_purple)) - .add(new Pair<>(R.color.theme_color_dark_purple, R.string.theme_color_dark_purple)) - .add(new Pair<>(R.color.theme_color_indigo, R.string.theme_color_indigo)) - .add(new Pair<>(R.color.theme_color_blue, R.string.theme_color_blue)) - .add(new Pair<>(R.color.theme_color_light_blue, R.string.theme_color_light_blue)) - .add(new Pair<>(R.color.theme_color_blue_green, R.string.theme_color_blue_green)) - .add(new Pair<>(R.color.theme_color_cyan, R.string.theme_color_cyan)) - .add(new Pair<>(R.color.theme_color_green, R.string.theme_color_green)) - .add(new Pair<>(R.color.theme_color_light_green, R.string.theme_color_light_green)) - .add(new Pair<>(R.color.theme_color_yellow_green, R.string.theme_color_yellow_green)) - .add(new Pair<>(R.color.theme_color_yellow, R.string.theme_color_yellow)) - .add(new Pair<>(R.color.theme_color_amber, R.string.theme_color_amber)) - .add(new Pair<>(R.color.theme_color_orange, R.string.theme_color_orange)) - .add(new Pair<>(R.color.theme_color_dark_orange, R.string.theme_color_dark_orange)) - .add(new Pair<>(R.color.theme_color_brown, R.string.theme_color_brown)) - .add(new Pair<>(R.color.theme_color_gray, R.string.theme_color_gray)) - .add(new Pair<>(R.color.theme_color_blue_gray, R.string.theme_color_blue_gray)) - .list(); - - public static void selectThemeColor(Context context) { - List colorItems = new ArrayList<>(COLOR_ITEMS.size()); - for (Pair item : COLOR_ITEMS) { - colorItems.add(new ColorSelectActivity.ColorItem(context.getString(item.second), - context.getResources().getColor(item.first))); - } - ColorSelectActivity.startColorSelect(context, context.getString(R.string.mt_color_picker_title), colorItems); - } - - @AfterViews - void setUpUI() { - setUpToolbar(); - getSupportFragmentManager().beginTransaction().replace(R.id.fragment_setting, new PreferenceFragment()).commit(); - } - - private void setUpToolbar() { - Toolbar toolbar = $(R.id.toolbar); - toolbar.setTitle(R.string.text_setting); - setSupportActionBar(toolbar); - getSupportActionBar().setDisplayHomeAsUpEnabled(true); - toolbar.setNavigationOnClickListener(v -> finish()); - } - - - public static class PreferenceFragment extends PreferenceFragmentCompat { - - private Map ACTION_MAP; - - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - } - - @Override - public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { - addPreferencesFromResource(R.xml.preferences); - } - - @Override - public void onDisplayPreferenceDialog(Preference preference) { - - DialogFragment dialogFragment = null; - if (preference instanceof ScriptDirPathPreference) { - dialogFragment = ScriptDirPathPreferenceFragmentCompat.newInstance(preference.getKey()); - } - if (dialogFragment != null) { - dialogFragment.setTargetFragment(this, 1234); - dialogFragment.show(this.getParentFragmentManager(), "androidx.preference.PreferenceFragment.DIALOG1"); - } else { - super.onDisplayPreferenceDialog(preference); - } - - } - - @Override - public void onStart() { - super.onStart(); - ACTION_MAP = new MapBuilder() -// .put(getString(R.string.text_theme_color), () -> selectThemeColor(getActivity())) -// .put(getString(R.string.text_check_for_updates), () -> new UpdateCheckDialog(getActivity()).show()) -// .put(getString(R.string.text_issue_report), () -> startActivity(new Intent(getActivity(), IssueReporterActivity.class).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK))) - .put(getString(R.string.text_about_me_and_repo), () -> startActivity(new Intent(getActivity(), AboutActivity_.class).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK))) - .put(getString(R.string.text_licenses), () -> showLicenseDialog()) - .put(getString(R.string.text_licenses_other), () -> showLicenseDialog2()) - .build(); - } - - - @Override - public boolean onPreferenceTreeClick(Preference preference) { - Runnable action = ACTION_MAP.get(preference.getTitle().toString()); - if (action != null) { - action.run(); - return true; - } else { - return super.onPreferenceTreeClick(preference); - } - } - - private void showLicenseDialog() { - new LicensesDialog.Builder(getActivity()) - .setNotices(R.raw.licenses) - .setIncludeOwnLicense(true) - .build() - .show(); - } - - private void showLicenseDialog2() { - new CommonMarkdownView.DialogBuilder(getActivity()) - .padding(36, 0, 36, 0) - .markdown(PFiles.read(getResources().openRawResource(R.raw.licenses_other))) - .title(R.string.text_licenses_other) - .positiveText(R.string.ok) - .canceledOnTouchOutside(false) - .show(); - } - - } -} diff --git a/app/src/main/java/org/autojs/autojs/ui/settings/SettingsActivity.kt b/app/src/main/java/org/autojs/autojs/ui/settings/SettingsActivity.kt new file mode 100644 index 000000000..8ac3e38d6 --- /dev/null +++ b/app/src/main/java/org/autojs/autojs/ui/settings/SettingsActivity.kt @@ -0,0 +1,164 @@ +package org.autojs.autojs.ui.settings + +import android.app.Activity +import android.content.Context +import android.content.Intent +import android.os.Bundle +import android.view.View +import androidx.appcompat.app.AppCompatActivity +import androidx.appcompat.widget.Toolbar +import androidx.core.util.Pair +import androidx.fragment.app.DialogFragment +import androidx.preference.Preference +import androidx.preference.PreferenceFragmentCompat +import com.stardust.pio.PFiles.read +import com.stardust.theme.app.ColorSelectActivity +import com.stardust.theme.app.ColorSelectActivity.ColorItem +import com.stardust.theme.util.ListBuilder +import de.psdev.licensesdialog.LicensesDialog +import org.autojs.autojs.ui.settings.LicenseInfo.install +import org.autojs.autojs.ui.widget.CommonMarkdownView.DialogBuilder +import org.autojs.autoxjs.R + +/** + * Created by Stardust on 2017/2/2. + * update by aaron 2022年1月16日 + */ +class SettingsActivity : AppCompatActivity() { + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_settings) + setUpUI() + } + + private fun setUpUI() { + setUpToolbar() + supportFragmentManager.beginTransaction() + .replace(R.id.fragment_setting, PreferenceFragment()).commit() + } + + private fun setUpToolbar() { + val toolbar = findViewById(R.id.toolbar) + toolbar.setTitle(R.string.text_setting) + setSupportActionBar(toolbar) + supportActionBar!!.setDisplayHomeAsUpEnabled(true) + toolbar.setNavigationOnClickListener { v: View? -> finish() } + } + + class PreferenceFragment : PreferenceFragmentCompat() { + private val ACTION_MAP = mutableMapOf Unit>() + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + ACTION_MAP.apply { + //.put(getString(R.string.text_theme_color), () -> selectThemeColor(getActivity())) + // .put(getString(R.string.text_check_for_updates), () -> new UpdateCheckDialog(getActivity()).show()) + // .put(getString(R.string.text_issue_report), () -> startActivity(new Intent(getActivity(), IssueReporterActivity.class).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK))) + put(getString(R.string.text_about_me_and_repo)) { + it.startActivity( + Intent(it, AboutActivity_::class.java) + .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + ) + } + put(getString(R.string.text_licenses)) { showLicenseDialog(it) } + put(getString(R.string.text_licenses_other)) { showLicenseDialog2(it) } + } + + } + + override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { + addPreferencesFromResource(R.xml.preferences) + } + + override fun onDisplayPreferenceDialog(preference: Preference) { + var dialogFragment: DialogFragment? = null + if (preference is ScriptDirPathPreference) { + ScriptDirPathPreferenceFragmentCompat.newInstance(preference.getKey())?.let { + it.setTargetFragment(this, 1234) + it.show( + this.parentFragmentManager, + "androidx.preference.PreferenceFragment.DIALOG1" + ) + return + } + } + super.onDisplayPreferenceDialog(preference) + } + + override fun onPreferenceTreeClick(preference: Preference): Boolean { + val action = ACTION_MAP[preference.title.toString()] + val activity = requireActivity() + return if (action != null) { + action(activity) + true + } else { + super.onPreferenceTreeClick(preference) + } + } + + companion object { + private fun showLicenseDialog(context: Context) { + LicensesDialog.Builder(context) + .setNotices(R.raw.licenses) + .setIncludeOwnLicense(true) + .build() + .show() + } + + private fun showLicenseDialog2(context: Context) { + DialogBuilder(context) + .padding(36, 0, 36, 0) + .markdown(read(context.resources.openRawResource(R.raw.licenses_other))) + .title(R.string.text_licenses_other) + .positiveText(R.string.ok) + .canceledOnTouchOutside(false) + .show() + } + } + } + + companion object { + init { + install() + } + + private val COLOR_ITEMS = ListBuilder>() + .add(Pair(R.color.theme_color_red, R.string.theme_color_red)) + .add(Pair(R.color.theme_color_pink, R.string.theme_color_pink)) + .add(Pair(R.color.theme_color_purple, R.string.theme_color_purple)) + .add(Pair(R.color.theme_color_dark_purple, R.string.theme_color_dark_purple)) + .add(Pair(R.color.theme_color_indigo, R.string.theme_color_indigo)) + .add(Pair(R.color.theme_color_blue, R.string.theme_color_blue)) + .add(Pair(R.color.theme_color_light_blue, R.string.theme_color_light_blue)) + .add(Pair(R.color.theme_color_blue_green, R.string.theme_color_blue_green)) + .add(Pair(R.color.theme_color_cyan, R.string.theme_color_cyan)) + .add(Pair(R.color.theme_color_green, R.string.theme_color_green)) + .add(Pair(R.color.theme_color_light_green, R.string.theme_color_light_green)) + .add(Pair(R.color.theme_color_yellow_green, R.string.theme_color_yellow_green)) + .add(Pair(R.color.theme_color_yellow, R.string.theme_color_yellow)) + .add(Pair(R.color.theme_color_amber, R.string.theme_color_amber)) + .add(Pair(R.color.theme_color_orange, R.string.theme_color_orange)) + .add(Pair(R.color.theme_color_dark_orange, R.string.theme_color_dark_orange)) + .add(Pair(R.color.theme_color_brown, R.string.theme_color_brown)) + .add(Pair(R.color.theme_color_gray, R.string.theme_color_gray)) + .add(Pair(R.color.theme_color_blue_gray, R.string.theme_color_blue_gray)) + .list() + + fun selectThemeColor(context: Context) { + val colorItems: MutableList = ArrayList(COLOR_ITEMS.size) + for (item in COLOR_ITEMS) { + colorItems.add( + ColorItem( + context.getString(item.second), + context.resources.getColor(item.first) + ) + ) + } + ColorSelectActivity.startColorSelect( + context, + context.getString(R.string.mt_color_picker_title), + colorItems + ) + } + } +} diff --git a/autojs/src/debug/kotlin/com/aiselp/debug/ObjectWatcher.kt b/autojs/src/debug/kotlin/com/aiselp/debug/ObjectWatcher.kt new file mode 100644 index 000000000..a6ee2ddc2 --- /dev/null +++ b/autojs/src/debug/kotlin/com/aiselp/debug/ObjectWatcher.kt @@ -0,0 +1,9 @@ +package com.aiselp.debug + +import leakcanary.AppWatcher.objectWatcher + +class ObjectWatcher : com.stardust.autojs.util.ObjectWatcher { + override fun watch(watchedObject: Any, description: String) { + objectWatcher.expectWeaklyReachable(watchedObject, description) + } +} \ No newline at end of file diff --git a/autojs/src/main/assets/modules/__images__.js b/autojs/src/main/assets/modules/__images__.js index f90359485..0fe78f0bf 100644 --- a/autojs/src/main/assets/modules/__images__.js +++ b/autojs/src/main/assets/modules/__images__.js @@ -170,7 +170,7 @@ module.exports = function (runtime, scope) { quality = quality == undefined ? 100 : quality; return javaImages.save(img, path, format, quality); } - + images.stopScreenCapturer = javaImages.stopScreenCapturer.bind(javaImages) images.saveImage = images.save; images.grayscale = function (img, dstCn) { diff --git a/autojs/src/main/java/com/stardust/autojs/core/console/ConsoleView.kt b/autojs/src/main/java/com/stardust/autojs/core/console/ConsoleView.kt index eacdf8d05..2a60a8d93 100644 --- a/autojs/src/main/java/com/stardust/autojs/core/console/ConsoleView.kt +++ b/autojs/src/main/java/com/stardust/autojs/core/console/ConsoleView.kt @@ -60,11 +60,10 @@ class ConsoleView : FrameLayout, LogListener { inflate(context, R.layout.console_view, this) if (attrs != null) { val typedArray = context.obtainStyledAttributes(attrs, R.styleable.ConsoleView) - typedArray.use { - for ((styleable, logLevel) in ATTRS) { - colors.put(logLevel, it.getColor(styleable, colors[logLevel])) - } + for ((styleable, logLevel) in ATTRS) { + colors.put(logLevel, typedArray.getColor(styleable, colors[logLevel])) } + typedArray.recycle() } mLogListRecyclerView = findViewById(R.id.log_list) val manager = LinearLayoutManager(context) @@ -118,10 +117,10 @@ class ConsoleView : FrameLayout, LogListener { override fun run() { refreshLog() if (!mShouldStopRefresh) { - postDelayed(this, REFRESH_INTERVAL.toLong()) + postDelayed(this, REFRESH_INTERVAL) } } - }, REFRESH_INTERVAL.toLong()) + }, REFRESH_INTERVAL) } override fun onDetachedFromWindow() { @@ -241,6 +240,6 @@ class ConsoleView : FrameLayout, LogListener { .entry(Log.ERROR, -0x2b0000) .entry(Log.ASSERT, -0xacb2) .sparseArray() - private const val REFRESH_INTERVAL = 100 + private const val REFRESH_INTERVAL = 100L } } diff --git a/autojs/src/main/java/com/stardust/autojs/core/image/capture/CaptureForegroundService.java b/autojs/src/main/java/com/stardust/autojs/core/image/capture/CaptureForegroundService.java deleted file mode 100644 index 761efb49e..000000000 --- a/autojs/src/main/java/com/stardust/autojs/core/image/capture/CaptureForegroundService.java +++ /dev/null @@ -1,82 +0,0 @@ -package com.stardust.autojs.core.image.capture; - -import static android.app.PendingIntent.FLAG_IMMUTABLE; - -import android.app.Notification; -import android.app.NotificationChannel; -import android.app.NotificationManager; -import android.app.PendingIntent; -import android.app.Service; -import android.content.Context; -import android.content.Intent; -import android.os.Build; -import android.os.IBinder; - -import androidx.annotation.Nullable; -import androidx.annotation.RequiresApi; -import androidx.core.app.NotificationCompat; - -import com.stardust.autojs.R; - -/** - * Created by TonyJiangWJ(https://github.com/TonyJiangWJ). - * From [TonyJiangWJ/Auto.js](https://github.com/TonyJiangWJ/Auto.js) - */ - -public class CaptureForegroundService extends Service { - - private static final int NOTIFICATION_ID = 2; - private static final String CHANNEL_ID = CaptureForegroundService.class.getName() + ".foreground"; - private static final String NOTIFICATION_TITLE = "前台截图服务运行中"; - - @Nullable - @Override - public IBinder onBind(Intent intent) { - return null; - } - - @Override - public int onStartCommand(Intent intent, int flags, int startId) { - return super.onStartCommand(intent, flags, startId); - } - - @Override - public void onCreate() { - super.onCreate(); - startForeground(NOTIFICATION_ID, buildNotification()); - } - - private Notification buildNotification() { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - createNotificationChannel(); - } - int flags = Build.VERSION.SDK_INT >= Build.VERSION_CODES.M ? FLAG_IMMUTABLE : 0; - PendingIntent contentIntent = PendingIntent.getActivity(this, 0, - new Intent(this, ScreenCaptureRequestActivity.class), flags); - - return new NotificationCompat.Builder(this, CHANNEL_ID) - .setContentTitle(NOTIFICATION_TITLE) - .setSmallIcon(R.drawable.autojs_logo) - .setWhen(System.currentTimeMillis()) - .setContentIntent(contentIntent) - .setChannelId(CHANNEL_ID) - .setVibrate(new long[0]) - .build(); - } - - @RequiresApi(api = Build.VERSION_CODES.O) - private void createNotificationChannel() { - NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); - assert manager != null; - NotificationChannel channel = new NotificationChannel(CHANNEL_ID, NOTIFICATION_TITLE, NotificationManager.IMPORTANCE_DEFAULT); - channel.setDescription(NOTIFICATION_TITLE); - channel.enableLights(false); - manager.createNotificationChannel(channel); - } - - @Override - public void onDestroy() { - super.onDestroy(); - stopForeground(true); - } -} \ No newline at end of file diff --git a/autojs/src/main/java/com/stardust/autojs/core/image/capture/CaptureForegroundService.kt b/autojs/src/main/java/com/stardust/autojs/core/image/capture/CaptureForegroundService.kt new file mode 100644 index 000000000..6f600da75 --- /dev/null +++ b/autojs/src/main/java/com/stardust/autojs/core/image/capture/CaptureForegroundService.kt @@ -0,0 +1,118 @@ +package com.stardust.autojs.core.image.capture + +import android.app.Notification +import android.app.NotificationChannel +import android.app.NotificationManager +import android.app.PendingIntent +import android.app.Service +import android.content.Intent +import android.media.projection.MediaProjection +import android.os.Build +import android.os.Handler +import android.os.IBinder +import android.util.Log +import androidx.annotation.RequiresApi +import androidx.core.app.NotificationCompat +import com.stardust.autojs.R +import com.stardust.autojs.core.image.capture.ScreenCaptureRequestActivity + +/** + * Created by TonyJiangWJ(https://github.com/TonyJiangWJ). + * From [TonyJiangWJ/Auto.js](https://github.com/TonyJiangWJ/Auto.js) + */ +class CaptureForegroundService : Service() { + val callback = object : MediaProjection.Callback() { + override fun onStop() { + stopSelf() + } + } + + override fun onBind(intent: Intent): IBinder? { + return null + } + + override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int { + super.onStartCommand(intent, flags, startId) + if (intent.action == (STOP)) { + Log.i(TAG, "stopSelf") + stopSelf() + } + mediaProjection?.registerCallback(callback, Handler(mainLooper)) + return START_NOT_STICKY + } + + override fun onCreate() { + super.onCreate() + startForeground(NOTIFICATION_ID, buildNotification()) + } + + + private fun buildNotification(): Notification { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + createNotificationChannel() + } + val flags = + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) PendingIntent.FLAG_IMMUTABLE else 0 + val contentIntent = PendingIntent.getActivity( + this, 0, + Intent(this, ScreenCaptureRequestActivity::class.java), flags + ) + return NotificationCompat.Builder(this, CHANNEL_ID) + .setContentTitle(NOTIFICATION_TITLE) + .setSmallIcon(R.drawable.autojs_logo) + .setWhen(System.currentTimeMillis()) + .setContentIntent(contentIntent) + .addAction(createExitAction()) + .setChannelId(CHANNEL_ID) + .setVibrate(LongArray(0)) + .build() + } + + @RequiresApi(api = Build.VERSION_CODES.O) + private fun createNotificationChannel() { + val manager = (getSystemService(NOTIFICATION_SERVICE) as NotificationManager) + val channel = NotificationChannel( + CHANNEL_ID, + NOTIFICATION_TITLE, + NotificationManager.IMPORTANCE_DEFAULT + ) + channel.description = NOTIFICATION_TITLE + channel.enableLights(false) + manager.createNotificationChannel(channel) + } + + private fun createExitAction(): NotificationCompat.Action { + val pendingIntent = PendingIntent.getService( + this, 12, + Intent(this, CaptureForegroundService::class.java).apply { + action = STOP + }, PendingIntent.FLAG_IMMUTABLE + ) + return NotificationCompat.Action.Builder( + null, + "停止截图", + pendingIntent + ).build() + } + + private fun removeNotification() { + (getSystemService(NOTIFICATION_SERVICE) as NotificationManager).cancel(NOTIFICATION_ID) + } + + override fun onDestroy() { + super.onDestroy() + mediaProjection?.unregisterCallback(callback) + mediaProjection?.stop() + removeNotification() + stopForeground(true) + } + + companion object { + var mediaProjection: MediaProjection? = null + private const val TAG = "CaptureService" + private const val STOP = "STOP_SERVICE" + private const val NOTIFICATION_ID = 2 + private val CHANNEL_ID = CaptureForegroundService::class.java.name + ".foreground" + private const val NOTIFICATION_TITLE = "前台截图服务运行中" + } +} \ No newline at end of file diff --git a/autojs/src/main/java/com/stardust/autojs/core/image/capture/ScreenCaptureManager.kt b/autojs/src/main/java/com/stardust/autojs/core/image/capture/ScreenCaptureManager.kt index 894d129c0..66b62cf43 100644 --- a/autojs/src/main/java/com/stardust/autojs/core/image/capture/ScreenCaptureManager.kt +++ b/autojs/src/main/java/com/stardust/autojs/core/image/capture/ScreenCaptureManager.kt @@ -4,6 +4,7 @@ import android.app.Activity import android.content.Context import android.content.Intent import android.media.projection.MediaProjection +import android.media.projection.MediaProjectionManager import com.stardust.app.OnActivityResultDelegate import kotlinx.coroutines.CompletableDeferred import kotlinx.coroutines.coroutineScope @@ -16,6 +17,7 @@ class ScreenCaptureManager : ScreenCaptureRequester { override suspend fun requestScreenCapture(context: Context, orientation: Int) { if (screenCapture?.available == true) { + screenCapture?.setOrientation(orientation, context) return } val result = if (context is OnActivityResultDelegate.DelegateHost && context is Activity) { @@ -24,10 +26,10 @@ class ScreenCaptureManager : ScreenCaptureRequester { ).request() } else { coroutineScope { - val result = CompletableDeferred() + val result = CompletableDeferred() ScreenCaptureRequestActivity.request(context, object : ScreenCaptureRequestActivity.Callback { - override fun onResult(data: MediaProjection?) { + override fun onResult(data: Intent?) { if (data != null) { result.complete(data) } else result.cancel(CancellationException("data is null")) @@ -36,14 +38,20 @@ class ScreenCaptureManager : ScreenCaptureRequester { result.await() } } + mediaProjection = + (context.getSystemService(Context.MEDIA_PROJECTION_SERVICE) as MediaProjectionManager).getMediaProjection( + Activity.RESULT_OK, + result + ) + CaptureForegroundService.mediaProjection = mediaProjection context.startService(Intent(context, CaptureForegroundService::class.java)) - mediaProjection = result - screenCapture = ScreenCapturer(result) + screenCapture = ScreenCapturer(mediaProjection!!, orientation) } override fun recycle() { screenCapture?.release() screenCapture = null mediaProjection?.stop() + mediaProjection = null } } \ No newline at end of file diff --git a/autojs/src/main/java/com/stardust/autojs/core/image/capture/ScreenCaptureRequestActivity.kt b/autojs/src/main/java/com/stardust/autojs/core/image/capture/ScreenCaptureRequestActivity.kt index c9c39e55b..6463872e5 100644 --- a/autojs/src/main/java/com/stardust/autojs/core/image/capture/ScreenCaptureRequestActivity.kt +++ b/autojs/src/main/java/com/stardust/autojs/core/image/capture/ScreenCaptureRequestActivity.kt @@ -3,7 +3,6 @@ package com.stardust.autojs.core.image.capture import android.app.Activity import android.content.Context import android.content.Intent -import android.media.projection.MediaProjection import android.os.Bundle import com.stardust.app.OnActivityResultDelegate import com.stardust.autojs.core.image.capture.ScreenCaptureRequester.ActivityScreenCaptureRequester @@ -16,7 +15,7 @@ import kotlinx.coroutines.launch */ class ScreenCaptureRequestActivity : Activity() { interface Callback { - fun onResult(data: MediaProjection?) + fun onResult(data: Intent?) } private val mOnActivityResultDelegateMediator = OnActivityResultDelegate.Mediator() diff --git a/autojs/src/main/java/com/stardust/autojs/core/image/capture/ScreenCaptureRequester.kt b/autojs/src/main/java/com/stardust/autojs/core/image/capture/ScreenCaptureRequester.kt index 14ac91235..c46dac36d 100644 --- a/autojs/src/main/java/com/stardust/autojs/core/image/capture/ScreenCaptureRequester.kt +++ b/autojs/src/main/java/com/stardust/autojs/core/image/capture/ScreenCaptureRequester.kt @@ -3,7 +3,6 @@ package com.stardust.autojs.core.image.capture import android.app.Activity import android.content.Context import android.content.Intent -import android.media.projection.MediaProjection import android.media.projection.MediaProjectionManager import com.stardust.app.OnActivityResultDelegate import kotlinx.coroutines.CompletableDeferred @@ -43,16 +42,14 @@ interface ScreenCaptureRequester { result.cancel() } - suspend fun request(): MediaProjection { + suspend fun request(): Intent { mActivity.startActivityForResult( (mActivity.getSystemService(Context.MEDIA_PROJECTION_SERVICE) as MediaProjectionManager).createScreenCaptureIntent(), REQUEST_CODE_MEDIA_PROJECTION ) val intent = result.await() recycle() - val mProjectionManager: MediaProjectionManager = - mActivity.getSystemService(Context.MEDIA_PROJECTION_SERVICE) as MediaProjectionManager - return mProjectionManager.getMediaProjection(Activity.RESULT_OK, intent) + return intent } fun recycle() { diff --git a/autojs/src/main/java/com/stardust/autojs/core/looper/LooperHelper.java b/autojs/src/main/java/com/stardust/autojs/core/looper/LooperHelper.java deleted file mode 100644 index 40e329e61..000000000 --- a/autojs/src/main/java/com/stardust/autojs/core/looper/LooperHelper.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.stardust.autojs.core.looper; - -import android.os.Looper; - -import java.util.concurrent.ConcurrentHashMap; - -/** - * Created by Stardust on 2017/12/27. - */ - -public class LooperHelper { - - private static volatile ConcurrentHashMap sLoopers = new ConcurrentHashMap<>(); - - public static void prepare() { - if (Looper.myLooper() == Looper.getMainLooper()) - return; - if (Looper.myLooper() == null) - Looper.prepare(); - Looper l = Looper.myLooper(); - if (l != null) - sLoopers.put(Thread.currentThread(), l); - } - - public static void quitForThread(Thread thread) { - Looper looper = sLoopers.remove(thread); - if (looper != null && looper != Looper.getMainLooper()) - looper.quit(); - } -} diff --git a/autojs/src/main/java/com/stardust/autojs/core/looper/Loopers.kt b/autojs/src/main/java/com/stardust/autojs/core/looper/Loopers.kt index 25591ac48..b31d32558 100644 --- a/autojs/src/main/java/com/stardust/autojs/core/looper/Loopers.kt +++ b/autojs/src/main/java/com/stardust/autojs/core/looper/Loopers.kt @@ -5,8 +5,9 @@ import android.os.MessageQueue import android.util.Log import com.stardust.autojs.rhino.AutoJsContext import com.stardust.autojs.runtime.ScriptRuntime -import com.stardust.autojs.runtime.exception.ScriptInterruptedException import com.stardust.lang.ThreadCompat +import kotlinx.coroutines.CompletableDeferred +import kotlinx.coroutines.runBlocking import org.mozilla.javascript.Context import java.util.concurrent.ConcurrentLinkedQueue @@ -42,7 +43,7 @@ class Loopers(val runtime: ScriptRuntime) { } } - private var waitWhenIdle: Boolean + private val isUiLooper: Boolean = Looper.myLooper() == Looper.getMainLooper() @Volatile private var mServantLooper: Looper? = null @@ -51,11 +52,13 @@ class Loopers(val runtime: ScriptRuntime) { val mTimer: Timer val myLooper: Looper + @Volatile + var available = true + init { prepare() myLooper = Looper.myLooper()!! mTimer = Timer(runtime, myLooper) - waitWhenIdle = myLooper == Looper.getMainLooper() } fun createAndAddAsyncTask(describe: String): AsyncTask { @@ -64,22 +67,21 @@ class Loopers(val runtime: ScriptRuntime) { return task } - fun addAsyncTask(task: AsyncTask) { - synchronized(myLooper) { - allTasks.add(task) - } + fun addAsyncTask(task: AsyncTask) = synchronized(myLooper) { + Log.i(LOG_TAG, "addAsyncTask $task") + if (!allTasks.contains(task)) allTasks.add(task) } - fun removeAsyncTask(task: AsyncTask) { - synchronized(myLooper) { - allTasks.remove(task) - mTimer.post(EMPTY_RUNNABLE) - } + + fun removeAsyncTask(task: AsyncTask) = synchronized(myLooper) { + allTasks.remove(task) + if (available) mTimer.post(EMPTY_RUNNABLE) } + private fun checkTask(): Boolean { allTasks.removeAll(allTasks.filter { it.isEnd }.toSet()) - return allTasks.isEmpty() + return allTasks.isNotEmpty() } private fun shouldQuitLooper(): Boolean { @@ -88,49 +90,33 @@ class Loopers(val runtime: ScriptRuntime) { if (mTimer.hasPendingCallbacks()) return false //检查是否有运行中的线程 if (checkTask()) return false - if (waitWhenIdle) return false - if ((Context.getCurrentContext() as AutoJsContext).hasPendingContinuation()) { - return false - } - return true + return !(Context.getCurrentContext() as AutoJsContext).hasPendingContinuation() } } - private fun initServantThread() { - ThreadCompat { - Looper.prepare() - val lock = this@Loopers as java.lang.Object - mServantLooper = Looper.myLooper() - synchronized(lock) { lock.notifyAll() } - Looper.loop() - }.start() - } - val servantLooper: Looper - get() { - if (mServantLooper == null) { - initServantThread() - val lock = this as java.lang.Object - synchronized(lock) { - try { - lock.wait() - } catch (e: InterruptedException) { - throw ScriptInterruptedException(e) - } + @Synchronized + get() = mServantLooper ?: runBlocking { + val looper = CompletableDeferred() + ThreadCompat { + Looper.prepare() + looper.complete(Looper.myLooper()!!) + Looper.loop() + }.apply { + setUncaughtExceptionHandler { t, e -> + mServantLooper = null + Log.e(LOG_TAG, "servantLooper exception", e) + t.interrupt() } - } - return mServantLooper!! + }.start() + mServantLooper = looper.await() + looper.await() } - @Deprecated("使用AsyncTask代替") - fun waitWhenIdle(b: Boolean) { - (Thread.currentThread() as? TimerThread)?.let { - it.loopers?.createAndAddAsyncTask("events") - } ?: createAndAddAsyncTask("events") - } fun recycle() { Log.d(LOG_TAG, "recycle") + available = false for (task in allTasks.filter { !it.isEnd }) { try { task.onStop(this) @@ -147,8 +133,8 @@ class Loopers(val runtime: ScriptRuntime) { } private fun prepare() { - if (Looper.myLooper() == Looper.getMainLooper()) return - if (Looper.myLooper() == null) LooperHelper.prepare() + if (isUiLooper) return + if (Looper.myLooper() == null) Looper.prepare() Looper.myQueue().addIdleHandler(MessageQueue.IdleHandler { if (this == runtime.loopers) { Log.d(LOG_TAG, "main looper queueIdle") diff --git a/autojs/src/main/java/com/stardust/autojs/core/looper/TimerThread.kt b/autojs/src/main/java/com/stardust/autojs/core/looper/TimerThread.kt index ecb9bfa74..5ae7c3cf0 100644 --- a/autojs/src/main/java/com/stardust/autojs/core/looper/TimerThread.kt +++ b/autojs/src/main/java/com/stardust/autojs/core/looper/TimerThread.kt @@ -7,7 +7,6 @@ import com.stardust.autojs.runtime.ScriptRuntime import com.stardust.autojs.runtime.exception.ScriptInterruptedException import com.stardust.lang.ThreadCompat import org.mozilla.javascript.Context -import java.util.concurrent.ConcurrentHashMap /** * Created by Stardust on 2017/12/27. @@ -27,7 +26,6 @@ open class TimerThread(private val mRuntime: ScriptRuntime, private val mTarget: override fun run() { loopers = Loopers(mRuntime) mTimer = loopers!!.mTimer - sTimerMap[currentThread()] = mTimer!! (mRuntime.engines.myEngine() as RhinoJavaScriptEngine).enterContext() notifyRunning() mTimer!!.post(mTarget) @@ -42,14 +40,9 @@ open class TimerThread(private val mRuntime: ScriptRuntime, private val mTarget: onExit() mTimer = null Context.exit() - sTimerMap.remove(currentThread(), mTimer) } } - override fun interrupt() { - LooperHelper.quitForThread(this) - super.interrupt() - } private fun notifyRunning() { synchronized(mRunningLock) { @@ -113,16 +106,4 @@ open class TimerThread(private val mRuntime: ScriptRuntime, private val mTarget: override fun toString(): String { return "Thread[$name,$priority]" } - - companion object { - private val sTimerMap = ConcurrentHashMap() - - @JvmStatic - fun getTimerForThread(thread: Thread): Timer? { - return sTimerMap[thread] - } - - val timerForCurrentThread: Timer? - get() = getTimerForThread(currentThread()) - } } \ No newline at end of file diff --git a/autojs/src/main/java/com/stardust/autojs/engine/LoopBasedJavaScriptEngine.java b/autojs/src/main/java/com/stardust/autojs/engine/LoopBasedJavaScriptEngine.java index 9c118f70e..533baa47a 100644 --- a/autojs/src/main/java/com/stardust/autojs/engine/LoopBasedJavaScriptEngine.java +++ b/autojs/src/main/java/com/stardust/autojs/engine/LoopBasedJavaScriptEngine.java @@ -4,13 +4,9 @@ import android.content.Context; import android.os.Handler; import android.os.Looper; -import android.os.MessageQueue; -import android.util.Log; -import com.stardust.autojs.core.looper.LooperHelper; import com.stardust.autojs.script.JavaScriptSource; import com.stardust.autojs.script.ScriptSource; -import com.stardust.util.Callback; import org.mozilla.javascript.ContinuationPending; @@ -76,7 +72,6 @@ public void execute(final ScriptSource source, final ExecuteCallback callback) { @Override public void forceStop() { - LooperHelper.quitForThread(getThread()); Activity activity = (Activity) getTag("activity"); if (activity != null) { activity.finish(); @@ -86,14 +81,12 @@ public void forceStop() { @Override public synchronized void destroy() { - Thread thread = getThread(); - LooperHelper.quitForThread(thread); super.destroy(); } @Override public void init() { - LooperHelper.prepare(); + if (Looper.myLooper() == null) Looper.prepare(); mHandler = new Handler(); super.init(); } diff --git a/autojs/src/main/java/com/stardust/autojs/rhino/debug/Debugger.java b/autojs/src/main/java/com/stardust/autojs/rhino/debug/Debugger.java index 32b39bd44..37e48d5b0 100644 --- a/autojs/src/main/java/com/stardust/autojs/rhino/debug/Debugger.java +++ b/autojs/src/main/java/com/stardust/autojs/rhino/debug/Debugger.java @@ -111,7 +111,7 @@ public void breakpoint(int line, boolean enabled) { private Dim createDim() { Dim dim = new Dim(); dim.setBreak(); - dim.setBreakOnExceptions(true); + dim.setBreakOnExceptions(false); dim.setGuiCallback(this); return dim; } diff --git a/autojs/src/main/java/com/stardust/autojs/runtime/ScriptRuntime.java b/autojs/src/main/java/com/stardust/autojs/runtime/ScriptRuntime.java index f4fc622e9..f0a2ae7b8 100644 --- a/autojs/src/main/java/com/stardust/autojs/runtime/ScriptRuntime.java +++ b/autojs/src/main/java/com/stardust/autojs/runtime/ScriptRuntime.java @@ -43,6 +43,7 @@ import com.stardust.autojs.runtime.exception.ScriptEnvironmentException; import com.stardust.autojs.runtime.exception.ScriptException; import com.stardust.autojs.runtime.exception.ScriptInterruptedException; +import com.stardust.autojs.util.ObjectWatcher; import com.stardust.concurrent.VolatileDispose; import com.stardust.lang.ThreadCompat; import com.stardust.pio.UncheckedIOException; @@ -67,8 +68,6 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -import leakcanary.AppWatcher; - /** * Created by Stardust on 2017/1/27. diff --git a/autojs/src/main/java/com/stardust/autojs/runtime/api/Events.java b/autojs/src/main/java/com/stardust/autojs/runtime/api/Events.java index ff0fbc91e..0fc3127e8 100644 --- a/autojs/src/main/java/com/stardust/autojs/runtime/api/Events.java +++ b/autojs/src/main/java/com/stardust/autojs/runtime/api/Events.java @@ -74,12 +74,13 @@ public class Events extends EventEmitter implements OnKeyListener, TouchObserver private boolean mListeningNotification = false; private boolean mListeningGesture = false; private boolean mListeningToast = false; - private ScriptRuntime mScriptRuntime; + private final ScriptRuntime mScriptRuntime; private volatile boolean mInterceptsAllKey = false; private KeyInterceptor mKeyInterceptor; private Set mInterceptedKeys = new HashSet<>(); public final BroadcastEmitter broadcast; + private final Loopers.AsyncTask task = new Loopers.AsyncTask("events"); public Events(Context context, AccessibilityBridge accessibilityBridge, ScriptRuntime runtime) { super(runtime.bridges); @@ -111,7 +112,7 @@ public void observeKey() { throw new ScriptException(mContext.getString(R.string.text_should_enable_key_observing)); } ensureHandler(); - mLoopers.waitWhenIdle(true); + mLoopers.addAsyncTask(task); mListeningKey = true; mAccessibilityBridge.ensureServiceEnabled(); service.getOnKeyObserver().addListener(this); @@ -127,7 +128,7 @@ public void observeTouch() { if (mTouchObserver != null) return; ensureHandler(); - mLoopers.waitWhenIdle(true); + mLoopers.addAsyncTask(task); mTouchObserver = new TouchObserver(InputEventObserver.getGlobal(mContext)); mTouchObserver.setOnTouchEventListener(this); mTouchObserver.observe(); @@ -218,14 +219,13 @@ public void setTouchEventTimeout(long touchEventTimeout) { mTouchEventTimeout = touchEventTimeout; } - @RequiresApi(Build.VERSION_CODES.JELLY_BEAN_MR2) public void observeNotification() { ScriptRuntime.requiresApi(18); if (mListeningNotification) return; mListeningNotification = true; ensureHandler(); - mLoopers.waitWhenIdle(true); + mLoopers.addAsyncTask(task); if (NotificationListenerService.Companion.getInstance() == null) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) { mContext.startActivity(new Intent(Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS)); @@ -241,7 +241,7 @@ public void observeToast() { mAccessibilityBridge.ensureServiceEnabled(); mListeningToast = true; ensureHandler(); - mLoopers.waitWhenIdle(true); + mLoopers.addAsyncTask(task); mAccessibilityBridge.getNotificationObserver().addToastListener(this); } @@ -256,7 +256,7 @@ public void observeGesture() { } service.getGestureEventDispatcher().addListener(this); ensureHandler(); - mLoopers.waitWhenIdle(true); + mLoopers.addAsyncTask(task); mListeningGesture = true; } diff --git a/autojs/src/main/java/com/stardust/autojs/runtime/api/Images.kt b/autojs/src/main/java/com/stardust/autojs/runtime/api/Images.kt index f4618182a..311077ffb 100644 --- a/autojs/src/main/java/com/stardust/autojs/runtime/api/Images.kt +++ b/autojs/src/main/java/com/stardust/autojs/runtime/api/Images.kt @@ -55,10 +55,12 @@ class Images( mScreenCaptureRequester.requestScreenCapture( mContext, orientation ) - mScreenCaptureRequester.screenCapture?.setOrientation(orientation, mContext) captureScreen() }.isSuccess } + fun stopScreenCapturer(){ + mScreenCaptureRequester.recycle() + } @Synchronized fun captureScreen(): ImageWrapper { diff --git a/autojs/src/main/java/com/stardust/autojs/runtime/api/Sensors.java b/autojs/src/main/java/com/stardust/autojs/runtime/api/Sensors.java index e741861ad..70de2ccb8 100644 --- a/autojs/src/main/java/com/stardust/autojs/runtime/api/Sensors.java +++ b/autojs/src/main/java/com/stardust/autojs/runtime/api/Sensors.java @@ -92,7 +92,6 @@ public Sensors(Context context, ScriptRuntime runtime) { mScriptBridges = runtime.bridges; mNoOpSensorEventEmitter = new SensorEventEmitter(runtime.bridges); mScriptRuntime = runtime; - runtime.loopers.addAsyncTask(mAsyncTask); } public SensorEventEmitter register(String sensorName) { @@ -115,6 +114,7 @@ public SensorEventEmitter register(String sensorName, int delay) { } private SensorEventEmitter register(@NonNull Sensor sensor, int delay) { + mScriptRuntime.loopers.addAsyncTask(mAsyncTask); SensorEventEmitter emitter = new SensorEventEmitter(mScriptBridges); mSensorManager.registerListener(emitter, sensor, delay); synchronized (mSensorEventEmitters) { diff --git a/autojs/src/main/java/com/stardust/autojs/runtime/api/Timers.kt b/autojs/src/main/java/com/stardust/autojs/runtime/api/Timers.kt index a5fdb7d96..0253a89e6 100644 --- a/autojs/src/main/java/com/stardust/autojs/runtime/api/Timers.kt +++ b/autojs/src/main/java/com/stardust/autojs/runtime/api/Timers.kt @@ -20,11 +20,12 @@ class Timers(private val mRuntime: ScriptRuntime) { fun getTimerForThread(thread: Thread): Timer { if (thread === mThreads.mainThread) { return mRuntime.loopers.mTimer - } - val timer = TimerThread.getTimerForThread(thread) - return if (timer == null && Looper.myLooper() == Looper.getMainLooper()) { + } else if (thread is TimerThread) { + return thread.timer + } else if (thread === Looper.getMainLooper().thread) { uiTimer - } else timer ?: mainTimer + } + return mainTimer } fun setTimeout(vararg args: Any?): Int { diff --git a/autojs/src/main/java/com/stardust/autojs/util/ObjectWatcher.kt b/autojs/src/main/java/com/stardust/autojs/util/ObjectWatcher.kt new file mode 100644 index 000000000..4a610e547 --- /dev/null +++ b/autojs/src/main/java/com/stardust/autojs/util/ObjectWatcher.kt @@ -0,0 +1,16 @@ +package com.stardust.autojs.util + +interface ObjectWatcher { + fun watch(watchedObject: Any, description: String) + + companion object { + val default: ObjectWatcher = try { + Class.forName("com.aiselp.debug.ObjectWatcher").newInstance() + as ObjectWatcher + } catch (e: Throwable) { + object : ObjectWatcher { + override fun watch(watchedObject: Any, description: String) {} + } + } + } +} \ No newline at end of file diff --git a/buildSrc/src/main/kotlin/Version.kt b/buildSrc/src/main/kotlin/Version.kt index dd6ea1ade..dd109049c 100644 --- a/buildSrc/src/main/kotlin/Version.kt +++ b/buildSrc/src/main/kotlin/Version.kt @@ -5,13 +5,13 @@ import java.io.File lateinit var versions: Versions private set -val kotlin_version = "1.6.21" -val compose_version = "1.2.0-rc01" +const val kotlin_version = "1.6.21" +const val compose_version = "1.2.0-rc01" fun initVersions(file: File) { val json = file.readText() versions = Gson().fromJson(json, Versions::class.java) - println(versions) + println(GsonBuilder().setPrettyPrinting().create().toJson(versions)) } data class Versions( @@ -20,17 +20,17 @@ data class Versions( @SerializedName("appVersionName") val appVersionName: String = "6.3.4", @SerializedName("buildTool") - val buildTool: String = "33.0.0", + val buildTool: String = "34.0.0", @SerializedName("compile") - val compile: Int = 33, + val compile: Int = 34, @SerializedName("devVersionCode") val devVersionCode: Int = 634, @SerializedName("devVersionName") val devVersionName: String = "6.3.4", @SerializedName("IDE") - val ide: String = "Android Studio Bumblebee | 2021.1.1", + val ide: String = "Android Studio Hedgehog | 2023.1.1", @SerializedName("JDK") - val jdk: String = "15", + val jdk: String = "17", @SerializedName("mini") val mini: Int = 21, @SerializedName("target") diff --git a/codeeditor/build.gradle.kts b/codeeditor/build.gradle.kts index 495a65f4f..8649cd8d2 100644 --- a/codeeditor/build.gradle.kts +++ b/codeeditor/build.gradle.kts @@ -18,6 +18,9 @@ android { testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" consumerProguardFiles("consumer-rules.pro") } + buildFeatures{ + viewBinding = true + } buildTypes { release { diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 43672e362..83f4ac3b5 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -47,7 +47,6 @@ androidx-activity-ktx = "androidx.activity:activity-ktx:1.5.1" commons-io = "commons-io:commons-io:2.6" eventbus = "org.greenrobot:eventbus:3.3.1" kotlinx-coroutines-android = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-android", version.ref = "kotlinx-coroutines-android" } -nanohttpd-webserver = "org.nanohttpd:nanohttpd-webserver:2.3.1" androidx-webkit = "androidx.webkit:webkit:1.7.0" core-ktx = { module = "androidx.core:core-ktx", version.ref = "core-ktx" } documentfile = "androidx.documentfile:documentfile:1.0.1" @@ -67,8 +66,8 @@ rxjava2-rxandroid = "io.reactivex.rxjava2:rxandroid:2.1.1" rxjava3 = "io.reactivex.rxjava3:rxjava:3.1.5" rxjava3-rxandroid = "io.reactivex.rxjava3:rxandroid:3.0.2" #leakcanary -leakcanary-android = "com.squareup.leakcanary:leakcanary-android:2.12" -leakcanary-object-watcher-android = "com.squareup.leakcanary:leakcanary-object-watcher-android:2.12" +leakcanary-android = "com.squareup.leakcanary:leakcanary-android:2.13" +leakcanary-object-watcher-android = "com.squareup.leakcanary:leakcanary-object-watcher-android:2.13" androidx-test-ext-junit = { group = "androidx.test.ext", name = "junit", version.ref = "androidx-test-ext-junit" } espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espresso-core" } diff --git a/project-versions.json b/project-versions.json index 4036633d5..2ca1cf382 100644 --- a/project-versions.json +++ b/project-versions.json @@ -3,10 +3,10 @@ "appVersionName": "6.5.7", "devVersionCode": 657, "devVersionName": "6.5.7", - "target": 26, + "target": 28, "mini": 21, - "compile": 33, - "buildTool": "33.0.0", + "compile": 34, + "buildTool": "34.0.0", "IDE": "Android Studio Bumblebee | 2021.1.1", "JDK": "17" }