修复已知问题

This commit is contained in:
TonyJiangWJ 2022-02-04 23:43:20 +08:00
parent b1d0fe5817
commit 87501555b8
9 changed files with 67 additions and 44 deletions

View File

@ -214,7 +214,8 @@ public class TimedTask extends BaseModel {
.putExtra(ScriptIntents.EXTRA_KEY_PATH, mScriptPath)
.putExtra(ScriptIntents.EXTRA_KEY_DELAY, mDelay)
.putExtra(ScriptIntents.EXTRA_KEY_LOOP_TIMES, mLoopTimes)
.putExtra(ScriptIntents.EXTRA_KEY_LOOP_INTERVAL, mInterval);
.putExtra(ScriptIntents.EXTRA_KEY_LOOP_INTERVAL, mInterval)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
}

View File

@ -369,6 +369,7 @@ public class ScriptOperations {
public void timedTask(ScriptFile scriptFile) {
TimedTaskSettingActivity_.intent(mContext)
.extra(ScriptIntents.EXTRA_KEY_PATH, scriptFile.getPath())
.flags(Intent.FLAG_ACTIVITY_NEW_TASK)
.start();
}

View File

@ -1,6 +1,7 @@
package org.autojs.autojs.ui.main.task;
import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.GradientDrawable;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@ -250,6 +251,7 @@ public class TaskListRecyclerView extends ThemeColorRecyclerView {
: TimedTaskSettingActivity.EXTRA_TASK_ID;
TimedTaskSettingActivity_.intent(getContext())
.extra(extra, task.getId())
.flags(Intent.FLAG_ACTIVITY_NEW_TASK)
.start();
}
}

View File

@ -85,6 +85,7 @@ public class CaptureForegroundService extends Service {
@Override
public void onDestroy() {
super.onDestroy();
GlobalScreenCapture.getInstance().foregroundServiceDown();
stopForeground(true);
}
}

View File

@ -12,16 +12,20 @@ import android.media.Image;
import android.media.ImageReader;
import android.media.projection.MediaProjection;
import android.media.projection.MediaProjectionManager;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.view.OrientationEventListener;
import com.stardust.autojs.runtime.ScriptRuntime;
import com.stardust.autojs.runtime.exception.ScriptException;
import com.stardust.autojs.runtime.exception.ScriptInterruptedException;
import com.stardust.lang.ThreadCompat;
import com.stardust.util.ScreenMetrics;
import org.mozilla.javascript.ast.Loop;
import java.util.Iterator;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicReference;
@ -37,7 +41,7 @@ public class GlobalScreenCapture {
public static final int ORIENTATION_PORTRAIT = Configuration.ORIENTATION_PORTRAIT;
private static final String TAG = "GlobalScreenCapture";
private final ConcurrentHashMap<Thread, Boolean> registeredThreads = new ConcurrentHashMap<>();
private final ConcurrentHashMap<ScriptRuntime, Boolean> registeredRuntimes = new ConcurrentHashMap<>();
private MediaProjectionManager mProjectionManager;
private ImageReader mImageReader;
@ -83,24 +87,16 @@ public class GlobalScreenCapture {
if (mScreenDensity == 0) {
mScreenDensity = ScreenMetrics.getDeviceScreenDensity();
}
if (!foregroundServiceStarted) {
try {
this.wait();
} catch (InterruptedException e) {
throw new ScriptInterruptedException();
}
}
awaitForegroundServiceIfNeeded();
mProjectionManager = (MediaProjectionManager) context.getSystemService(Context.MEDIA_PROJECTION_SERVICE);
mMediaProjection = mProjectionManager.getMediaProjection(Activity.RESULT_OK, (Intent) data.clone());
mContext = context;
mData = (Intent) data.clone();
new Thread(() -> {
Looper.prepare();
mHandler = new Handler(Looper.getMainLooper());
synchronized (GlobalScreenCapture.this) {
GlobalScreenCapture.this.notifyAll();
}
Looper.loop();
}).start();
synchronized (this) {
try {
@ -114,13 +110,35 @@ public class GlobalScreenCapture {
hasPermission = true;
}
private void awaitForegroundServiceIfNeeded() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && !foregroundServiceStarted) {
try {
this.wait();
} catch (InterruptedException e) {
throw new ScriptInterruptedException();
}
}
}
public synchronized void notifyStarted() {
this.foregroundServiceStarted = true;
this.notify();
}
public void foregroundServiceDown() {
this.foregroundServiceStarted = false;
}
public synchronized boolean hasPermission() {
return hasPermission;
if (!hasPermission) {
return false;
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && !foregroundServiceStarted) {
// 前台服务可能丢失重新获取
mContext.startForegroundService(new Intent(mContext, CaptureForegroundService.class));
awaitForegroundServiceIfNeeded();
return foregroundServiceStarted;
}
return true;
}
public void setOrientation(int orientation) {
@ -129,9 +147,12 @@ public class GlobalScreenCapture {
}
mOrientation = orientation;
mDetectedOrientation = mContext.getResources().getConfiguration().orientation;
refreshVirtualDisplay(mOrientation == ORIENTATION_AUTO ? mDetectedOrientation : mOrientation);
refreshVirtualDisplay(getOrientation());
}
private int getOrientation() {
return mOrientation == ORIENTATION_AUTO ? mDetectedOrientation : mOrientation;
}
private void observeOrientation() {
mOrientationEventListener = new OrientationEventListener(mContext) {
@ -179,6 +200,7 @@ public class GlobalScreenCapture {
mMediaProjection = mProjectionManager.getMediaProjection(Activity.RESULT_OK, (Intent) mData.clone());
} catch (Exception e) {
Log.d(TAG, "grantMediaProjection: 获取新projection失败 可能只是MIUI的bug " + e);
release();
}
}
@ -246,33 +268,35 @@ public class GlobalScreenCapture {
startTime = System.currentTimeMillis();
Log.d(TAG, "capture: 获取截图失败刷新virtualDisplay");
this.grantMediaProjection();
this.refreshVirtualDisplay(mOrientation);
this.refreshVirtualDisplay(getOrientation());
}
}
throw new ScriptInterruptedException();
}
public synchronized void unregister(Looper looper) {
Log.d(TAG, "unregister: " + looper.getThread().getName());
registeredThreads.remove(looper.getThread());
Iterator<Thread> keyThreads = registeredThreads.keySet().iterator();
while (keyThreads.hasNext()) {
Thread thread = keyThreads.next();
if (!thread.isAlive()) {
keyThreads.remove();
public synchronized void unregister(ScriptRuntime runtime) {
Log.d(TAG, "unregister: " + runtime);
registeredRuntimes.remove(runtime);
Iterator<ScriptRuntime> keyRuntime = registeredRuntimes.keySet().iterator();
while (keyRuntime.hasNext()) {
ScriptRuntime scriptRuntime = keyRuntime.next();
Looper looper = scriptRuntime.loopers.getMainLooper();
if (looper == null || !looper.getThread().isAlive()) {
keyRuntime.remove();
}
}
noRegister = registeredThreads.size() == 0;
noRegister = registeredRuntimes.size() == 0;
if (noRegister) {
Log.d(TAG, "全部引擎已注销,释放截图权限,清除通知");
release();
}
}
public synchronized void register(Looper looper) {
Log.d(TAG, "新引擎注册:" + looper.getThread().getName() + " hasPermission? " + hasPermission);
public synchronized void register(ScriptRuntime runtime) {
Looper looper = runtime.loopers.getMainLooper();
Log.d(TAG, "新引擎注册:" + (looper != null ? looper.getThread().getName() : runtime.engines.myEngine().toString()) + " hasPermission? " + hasPermission);
noRegister = false;
registeredThreads.put(looper.getThread(), true);
registeredRuntimes.put(runtime, true);
}
private void release() {

View File

@ -66,7 +66,7 @@ public class ScriptExecuteActivity extends AppCompatActivity {
return;
}
ScriptExecution execution = ScriptEngineService.getInstance().getScriptExecution(executionId);
if (execution == null || !(execution instanceof ActivityScriptExecution)) {
if (!(execution instanceof ActivityScriptExecution)) {
super.finish();
return;
}

View File

@ -216,9 +216,7 @@ public class ScriptRuntime {
this.automator = new SimpleActionAutomator(accessibilityBridge, this);
automator.setScreenMetrics(mScreenMetrics);
this.info = accessibilityBridge.getInfoProvider();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
images = new Images(context, this, builder.mScreenCaptureRequester);
}
images = new Images(context, this, builder.mScreenCaptureRequester);
engines = new Engines(builder.mEngineService, this);
dialogs = new Dialogs(this);
device = new Device(context);

View File

@ -30,6 +30,7 @@ import com.stardust.concurrent.VolatileDispose;
import com.stardust.pio.UncheckedIOException;
import com.stardust.util.ScreenMetrics;
import org.mozilla.javascript.ast.Loop;
import org.opencv.core.Point;
import org.opencv.core.Rect;
import org.opencv.imgproc.Imgproc;
@ -83,12 +84,11 @@ public class Images {
if (GlobalScreenCapture.getInstance().hasPermission()) {
Log.d(TAG, "requestScreenCapture hasPermission 直接注册");
GlobalScreenCapture.getInstance().setOrientation(orientation);
GlobalScreenCapture.getInstance().register(mScriptRuntime.get().loopers.getMainLooper());
new Handler(Looper.getMainLooper())
.post(() -> {
promiseAdapter.awaitResolver();
promiseAdapter.resolve(true);
});
GlobalScreenCapture.getInstance().register(mScriptRuntime.get());
new Thread(() -> {
promiseAdapter.awaitResolver();
new Handler(Looper.getMainLooper()).postDelayed(() -> promiseAdapter.resolve(true), 50);
}).start();
return promiseAdapter;
}
}
@ -97,7 +97,7 @@ public class Images {
mScreenCaptureRequester.setOnActivityResultCallback((result, data) -> {
if (result == Activity.RESULT_OK) {
GlobalScreenCapture.getInstance().initCapture(mContext, data, orientation);
GlobalScreenCapture.getInstance().register(mScriptRuntime.get().loopers.getMainLooper());
GlobalScreenCapture.getInstance().register(mScriptRuntime.get());
promiseAdapter.resolve(true);
} else {
promiseAdapter.resolve(false);
@ -277,7 +277,7 @@ public class Images {
public void releaseScreenCapturer() {
if (GlobalScreenCapture.getInstance().hasPermission()) {
synchronized (GlobalScreenCapture.getInstance()) {
GlobalScreenCapture.getInstance().unregister(mScriptRuntime.get().loopers.getMainLooper());
GlobalScreenCapture.getInstance().unregister(mScriptRuntime.get());
}
}
}

View File

@ -32,9 +32,7 @@ public class VolatileDispose<T> {
} catch (InterruptedException e) {
try {
throw exception.newInstance();
} catch (InstantiationException e1) {
throw new RuntimeException(e1);
} catch (IllegalAccessException e1) {
} catch (InstantiationException | IllegalAccessException e1) {
throw new RuntimeException(e1);
}
}
@ -52,9 +50,7 @@ public class VolatileDispose<T> {
} catch (InterruptedException e) {
try {
throw exception.newInstance();
} catch (InstantiationException e1) {
throw new RuntimeException(e1);
} catch (IllegalAccessException e1) {
} catch (InstantiationException | IllegalAccessException e1) {
throw new RuntimeException(e1);
}
}