Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
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;
Expand All @@ -16,11 +15,12 @@
import androidx.annotation.RequiresApi;
import androidx.core.app.NotificationCompat;

import com.stardust.app.service.AbstractAutoService;

import org.autojs.autoxjs.R;
import org.autojs.autojs.ui.main.MainActivity;

public class ForegroundService extends Service {

public class ForegroundService extends AbstractAutoService {

private static final int NOTIFICATION_ID = 1;
private static final String CHANEL_ID = ForegroundService.class.getName() + ".foreground";
Expand All @@ -33,7 +33,7 @@ public static void start(Context context) {
}
}

public static void stop(Context context){
public static void stop(Context context) {
context.stopService(new Intent(context, ForegroundService.class));
}

Expand Down
56 changes: 44 additions & 12 deletions app/src/main/java/org/autojs/autojs/ui/main/drawer/DrawerPage.kt
Original file line number Diff line number Diff line change
Expand Up @@ -11,33 +11,62 @@ import android.widget.TextView
import android.widget.Toast
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.foundation.*
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.navigationBars
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.statusBars
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.windowInsetsBottomHeight
import androidx.compose.foundation.layout.windowInsetsTopHeight
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.*
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.AlertDialog
import androidx.compose.material.ButtonDefaults
import androidx.compose.material.MaterialTheme
import androidx.compose.material.RadioButton
import androidx.compose.material.Surface
import androidx.compose.material.Text
import androidx.compose.material.TextButton
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Edit
import androidx.compose.material.icons.filled.ExitToApp
import androidx.compose.material.icons.filled.Notifications
import androidx.compose.material.icons.filled.Settings
import androidx.compose.runtime.*
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.viewinterop.AndroidView
import androidx.compose.ui.window.Dialog
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.preference.PreferenceManager
import coil.compose.rememberAsyncImagePainter
import com.stardust.app.GlobalAppContext
import com.stardust.app.isOpPermissionGranted
import com.stardust.app.permission.DrawOverlaysPermission
import com.stardust.app.permission.DrawOverlaysPermission.launchCanDrawOverlaysSettings
import com.stardust.app.permission.PermissionsSettingsUtil
import com.stardust.app.service.AbstractAutoService.Companion.stopAllServices
import com.stardust.enhancedfloaty.FloatyService
import com.stardust.notification.NotificationListenerService
import com.stardust.toast
Expand All @@ -46,7 +75,11 @@ import com.stardust.view.accessibility.AccessibilityService
import io.github.g00fy2.quickie.QRResult
import io.github.g00fy2.quickie.ScanQRCode
import io.noties.markwon.Markwon
import kotlinx.coroutines.*
import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.autojs.autojs.Pref
import org.autojs.autojs.autojs.AutoJs
import org.autojs.autojs.devplugin.DevPlugin
Expand All @@ -60,11 +93,10 @@ 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.autoxjs.BuildConfig
import org.autojs.autoxjs.R
import org.joda.time.DateTimeZone
import org.joda.time.Instant
import org.autojs.autoxjs.BuildConfig
import androidx.compose.ui.text.style.TextAlign

private const val TAG = "DrawerPage"
private const val URL_DEV_PLUGIN = "https://github.com/kkevsekk1/Auto.js-VSCode-Extension"
Expand Down Expand Up @@ -304,11 +336,11 @@ private fun BottomButtons() {
}

fun exitCompletely(context: Context) {
if (context is Activity) context.finish()
AutoJs.getInstance().scriptEngineService.stopAll()
FloatyWindowManger.hideCircularMenu()
ForegroundService.stop(context)
context.stopService(Intent(context, FloatyService::class.java))
AutoJs.getInstance().scriptEngineService.stopAll()
stopAllServices()
if (context is Activity) context.finish()
}

@Composable
Expand Down
8 changes: 2 additions & 6 deletions autojs/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ android {
dependencies {
androidTestImplementation(libs.espresso.core)
debugImplementation(libs.leakcanary.android)
implementation(libs.leakcanary.`object`.watcher.android)
implementation(libs.leakcanary.watcher.android)
testImplementation(libs.junit)

implementation(libs.documentfile)
Expand Down Expand Up @@ -67,10 +67,6 @@ dependencies {
// libs
api(fileTree("../app/libs"){include("dx.jar", "rhino-1.7.14-jdk7.jar")})
api("cz.adaptech:tesseract4android:4.1.1")
api("com.google.mlkit:text-recognition:16.0.0-beta5")
api("com.google.mlkit:text-recognition-chinese:16.0.0-beta5")
api("com.google.mlkit:text-recognition-devanagari:16.0.0-beta5")
api("com.google.mlkit:text-recognition-japanese:16.0.0-beta5")
api("com.google.mlkit:text-recognition-korean:16.0.0-beta5")
implementation(libs.bundles.mlkit)
}

4 changes: 2 additions & 2 deletions autojs/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
<!-- termux -->
<uses-permission android:name="com.termux.permission.RUN_COMMAND"/>
<uses-permission android:name="com.termux.permission.RUN_COMMAND" />
<uses-permission
android:name="android.permission.WRITE_SETTINGS"
tools:ignore="ProtectedPermissions" />
Expand All @@ -24,6 +24,7 @@
<!--写联系人的权限-->
<uses-permission android:name="android.permission.WRITE_CONTACTS" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PROJECTION" />

<application>
<activity
android:name=".execution.ScriptExecuteActivity"
Expand Down Expand Up @@ -59,7 +60,6 @@
android:name="com.stardust.autojs.core.image.capture.CaptureForegroundService"
android:exported="false"
android:foregroundServiceType="mediaProjection" />

</application>

</manifest>
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import android.graphics.Bitmap;
import android.graphics.Color;
import android.media.Image;
import android.os.Build;

import com.stardust.autojs.core.opencv.Mat;
import com.stardust.autojs.core.opencv.OpenCVHelper;
Expand All @@ -16,7 +15,7 @@
import java.io.FileOutputStream;
import java.nio.ByteBuffer;

import androidx.annotation.RequiresApi;
import androidx.annotation.NonNull;

/**
* Created by Stardust on 2017/11/25.
Expand Down Expand Up @@ -139,10 +138,7 @@ public Bitmap getBitmap() {
}

public void recycle() {
if (mBitmap != null) {
mBitmap.recycle();
mBitmap = null;
}
mBitmap = null;
if (mMat != null) {
OpenCVHelper.release(mMat);
mMat = null;
Expand All @@ -155,6 +151,7 @@ public void ensureNotRecycled() {
throw new IllegalStateException("image has been recycled");
}

@NonNull
public ImageWrapper clone() {
ensureNotRecycled();
if (mBitmap == null) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.stardust.autojs.core.image;

import android.util.Log;
import android.util.TimingLogger;

import com.stardust.autojs.core.opencv.OpenCVHelper;
Expand Down Expand Up @@ -72,70 +73,87 @@ public static Point fastTemplateMatching(Mat img, Mat template, int matchMethod,
*/
public static List<Match> fastTemplateMatching(Mat img, Mat template, int matchMethod, float weakThreshold, float strictThreshold, int maxLevel, int limit) {
TimingLogger logger = new TimingLogger(LOG_TAG, "fast_tm");
if (maxLevel == MAX_LEVEL_AUTO) {
//自动选取金字塔层数
maxLevel = selectPyramidLevel(img, template);
logger.addSplit("selectPyramidLevel:" + maxLevel);
}
//保存每一轮匹配到模板图片在原图片的位置
List<Match> finalMatchResult = new ArrayList<>();
List<Match> previousMatchResult = Collections.emptyList();
boolean isFirstMatching = true;
for (int level = maxLevel; level >= 0; level--) {
// 放缩图片
List<Match> currentMatchResult = new ArrayList<>();
Mat src = getPyramidDownAtLevel(img, level);
Mat currentTemplate = getPyramidDownAtLevel(template, level);
// 如果在上一轮中没有匹配到图片,则考虑是否退出匹配
if (previousMatchResult.isEmpty()) {
// 如果不是第一次匹配,并且不满足shouldContinueMatching的条件,则直接退出匹配
if (!isFirstMatching && !shouldContinueMatching(level, maxLevel)) {
break;
// 创建资源回收列表
List<Mat> resourcesToRelease = new ArrayList<>();

try {
if (maxLevel == MAX_LEVEL_AUTO) {
maxLevel = selectPyramidLevel(img, template);
logger.addSplit("selectPyramidLevel:" + maxLevel);
}
List<Match> finalMatchResult = new ArrayList<>();
List<Match> previousMatchResult = Collections.emptyList();
boolean isFirstMatching = true;
for (int level = maxLevel; level >= 0; level--) {
List<Match> currentMatchResult = new ArrayList<>();
Mat src = getPyramidDownAtLevel(img, level);
Mat currentTemplate = getPyramidDownAtLevel(template, level);

// +++ 添加到释放列表 +++
if (src != img) {
resourcesToRelease.add(src);
}
Mat matchResult = matchTemplate(src, currentTemplate, matchMethod);
getBestMatched(matchResult, currentTemplate, matchMethod, weakThreshold, currentMatchResult, limit, null);
OpenCVHelper.release(matchResult);
} else {
for (Match match : previousMatchResult) {
// 根据上一轮的匹配点,计算本次匹配的区域
Rect r = getROI(match.point, src, currentTemplate);
Mat m = new Mat(src, r);
Mat matchResult = matchTemplate(m, currentTemplate, matchMethod);
getBestMatched(matchResult, currentTemplate, matchMethod, weakThreshold, currentMatchResult, limit, r);
OpenCVHelper.release(m);
OpenCVHelper.release(matchResult);
if (currentTemplate != template) {
resourcesToRelease.add(currentTemplate);
}
}

if (src != img)
OpenCVHelper.release(src);
if (currentTemplate != template)
OpenCVHelper.release(currentTemplate);

logger.addSplit("level:" + level + ", result:" + previousMatchResult);

// 把满足强阈值的点找出来,加到最终结果列表
if (!currentMatchResult.isEmpty()) {
Iterator<Match> iterator = currentMatchResult.iterator();
while (iterator.hasNext()) {
Match match = iterator.next();
if (match.similarity >= strictThreshold) {
pyrUp(match.point, level);
finalMatchResult.add(match);
iterator.remove();
// 如果在上一轮中没有匹配到图片,则考虑是否退出匹配
if (previousMatchResult.isEmpty()) {
// 如果不是第一次匹配,并且不满足shouldContinueMatching的条件,则直接退出匹配
if (!isFirstMatching && !shouldContinueMatching(level, maxLevel)) {
break;
}
Mat matchResult = matchTemplate(src, currentTemplate, matchMethod);
resourcesToRelease.add(matchResult);
getBestMatched(matchResult, currentTemplate, matchMethod, weakThreshold, currentMatchResult, limit, null);
} else {
for (Match match : previousMatchResult) {
Rect r = getROI(match.point, src, currentTemplate);
Mat m = new Mat(src, r);
Mat matchResult = matchTemplate(m, currentTemplate, matchMethod);

// +++ 添加到释放列表 +++
resourcesToRelease.add(m);
resourcesToRelease.add(matchResult);

getBestMatched(matchResult, currentTemplate, matchMethod, weakThreshold, currentMatchResult, limit, r);
}
}
// 如果所有结果都满足强阈值,则退出循环,返回最终结果
if (currentMatchResult.isEmpty()) {
break;

logger.addSplit("level:" + level + ", result:" + previousMatchResult);

// 把满足强阈值的点找出来,加到最终结果列表
if (!currentMatchResult.isEmpty()) {
Iterator<Match> iterator = currentMatchResult.iterator();
while (iterator.hasNext()) {
Match match = iterator.next();
if (match.similarity >= strictThreshold) {
pyrUp(match.point, level);
finalMatchResult.add(match);
iterator.remove();
}
}
// 如果所有结果都满足强阈值,则退出循环,返回最终结果
if (currentMatchResult.isEmpty()) {
break;
}
}
isFirstMatching = false;
previousMatchResult = currentMatchResult;
}
logger.addSplit("result:" + finalMatchResult);
logger.dumpToLog();
return finalMatchResult;
} finally {
// 释放所有中间Mat对象
for (Mat mat : resourcesToRelease) {
try {
OpenCVHelper.release(mat);
} catch (Exception e) {
Log.e(LOG_TAG, "Error releasing Mat resource", e);
}
}
isFirstMatching = false;
previousMatchResult = currentMatchResult;
}
logger.addSplit("result:" + finalMatchResult);
logger.dumpToLog();
return finalMatchResult;
}


Expand Down
Loading