diff --git a/app/build.gradle b/app/build.gradle index 1da94332..d6577ba1 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -9,8 +9,8 @@ android { applicationId "com.stardust.scriptdroid" minSdkVersion 19 targetSdkVersion 23 - versionCode 134 - versionName "2.0.12 Alpha" + versionCode 136 + versionName "2.0.12 Alpha3日志版" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" multiDexEnabled true ndk { diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index c6a7458e..54ccb915 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -9,6 +9,7 @@ + diff --git a/app/src/main/java/com/stardust/scriptdroid/App.java b/app/src/main/java/com/stardust/scriptdroid/App.java index b18636f9..7b97eb62 100644 --- a/app/src/main/java/com/stardust/scriptdroid/App.java +++ b/app/src/main/java/com/stardust/scriptdroid/App.java @@ -13,6 +13,7 @@ import com.stardust.scriptdroid.autojs.AutoJs; import com.stardust.scriptdroid.statics.ScriptStatics; import com.stardust.scriptdroid.tool.CrashHandler; import com.stardust.scriptdroid.tool.JsBeautifierFactory; +import com.stardust.scriptdroid.tool.Logcat; import com.stardust.scriptdroid.ui.error.ErrorReportActivity; import com.stardust.theme.ThemeColor; import com.stardust.theme.ThemeColorManager; @@ -43,6 +44,8 @@ public class App extends MultiDexApplication { setUpDebugEnvironment(); init(); registerActivityLifecycleCallback(); + Logcat.deleteLogFile(); + Logcat.startLogSavingIfNeeded(); } private void setUpStaticsTool() { diff --git a/app/src/main/java/com/stardust/scriptdroid/autojs/AutoJs.java b/app/src/main/java/com/stardust/scriptdroid/autojs/AutoJs.java index 41d85602..036ddb36 100644 --- a/app/src/main/java/com/stardust/scriptdroid/autojs/AutoJs.java +++ b/app/src/main/java/com/stardust/scriptdroid/autojs/AutoJs.java @@ -105,6 +105,7 @@ public class AutoJs implements AccessibilityBridge { .setScreenCaptureRequester(mScreenCaptureRequester) .setAccessibilityBridge(AutoJs.this) .setUiHandler(mUiHandler) + .setAppUtils(mAppUtils) .setShellSupplier(new Supplier() { @Override public AbstractShell get() { diff --git a/app/src/main/java/com/stardust/scriptdroid/service/AccessibilityWatchDogService.java b/app/src/main/java/com/stardust/scriptdroid/service/AccessibilityWatchDogService.java index aafd6d05..a9e5ef0f 100644 --- a/app/src/main/java/com/stardust/scriptdroid/service/AccessibilityWatchDogService.java +++ b/app/src/main/java/com/stardust/scriptdroid/service/AccessibilityWatchDogService.java @@ -53,10 +53,8 @@ public class AccessibilityWatchDogService extends AccessibilityService { @Override public void onAccessibilityEvent(final AccessibilityEvent event) { - if (event.getEventType() == AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED) { - - } Log.v(TAG, "onAccessibilityEvent: " + event); + super.onAccessibilityEvent(event); if (!containsAllEventTypes && !eventTypes.contains(event.getEventType())) return; for (Map.Entry entry : mDelegates.entrySet()) { diff --git a/app/src/main/java/com/stardust/scriptdroid/statics/ScriptStaticsRecord.java b/app/src/main/java/com/stardust/scriptdroid/statics/ScriptStaticsRecord.java index 1e682c10..cf3c217c 100644 --- a/app/src/main/java/com/stardust/scriptdroid/statics/ScriptStaticsRecord.java +++ b/app/src/main/java/com/stardust/scriptdroid/statics/ScriptStaticsRecord.java @@ -9,7 +9,6 @@ import com.pushtorefresh.storio.sqlite.annotations.StorIOSQLiteType; */ @StorIOSQLiteType(table = SQLiteStaticsStorage.TABLE_NAME) - public class ScriptStaticsRecord { @StorIOSQLiteColumn(name = "name", key = true) diff --git a/app/src/main/java/com/stardust/scriptdroid/tool/Logcat.java b/app/src/main/java/com/stardust/scriptdroid/tool/Logcat.java new file mode 100644 index 00000000..5c22bca5 --- /dev/null +++ b/app/src/main/java/com/stardust/scriptdroid/tool/Logcat.java @@ -0,0 +1,33 @@ +package com.stardust.scriptdroid.tool; + +import com.stardust.scriptdroid.script.StorageScriptProvider; + +import java.io.File; +import java.io.IOException; + +/** + * Created by Stardust on 2017/5/22. + */ + +public class Logcat { + + private static final String LOG_PATH = StorageScriptProvider.DEFAULT_DIRECTORY_PATH + "log.txt"; + private static final String DISABLE_PATH = StorageScriptProvider.DEFAULT_DIRECTORY_PATH + "disable_log.txt"; + private static Process sLogSavingProcess; + + public static void startLogSavingIfNeeded() { + if (sLogSavingProcess != null) + return; + if (new File(DISABLE_PATH).exists()) + return; + try { + sLogSavingProcess = Runtime.getRuntime().exec("logcat -f " + LOG_PATH); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public static void deleteLogFile() { + new File(LOG_PATH).delete(); + } +} diff --git a/autojs/src/main/assets/modules/__images__.js b/autojs/src/main/assets/modules/__images__.js index abffa120..932227da 100644 --- a/autojs/src/main/assets/modules/__images__.js +++ b/autojs/src/main/assets/modules/__images__.js @@ -11,6 +11,13 @@ module.exports = function(__runtime__, scope){ images.saveImage = __runtime__.images.saveImage.bind(__runtime__.images); images.findColor = function(img, color, options){ + if(typeof(color) == 'string'){ + if(color.startsWith('#')){ + color = parseInt('0x' + color.substring(1)); + }else{ + color = parseInt('0x' + color); + } + } options = options || {}; var region = options.region || []; x = region[0] || 0; diff --git a/autojs/src/main/java/com/stardust/autojs/runtime/AbstractScriptRuntime.java b/autojs/src/main/java/com/stardust/autojs/runtime/AbstractScriptRuntime.java index 278ca5f8..10ef41d2 100644 --- a/autojs/src/main/java/com/stardust/autojs/runtime/AbstractScriptRuntime.java +++ b/autojs/src/main/java/com/stardust/autojs/runtime/AbstractScriptRuntime.java @@ -39,8 +39,8 @@ public abstract class AbstractScriptRuntime { @ScriptVariable public Images images; - public AbstractScriptRuntime(Context context, Console console, AccessibilityBridge bridge, ScreenCaptureRequester screenCaptureRequester) { - this.app = new AppUtils(context); + public AbstractScriptRuntime(Context context, Console console, AccessibilityBridge bridge, AppUtils appUtils, ScreenCaptureRequester screenCaptureRequester) { + this.app = appUtils; this.console = console; this.automator = new SimpleActionAutomator(bridge, this); this.info = bridge.getInfoProvider(); 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 e59d7761..cf53b5d3 100644 --- a/autojs/src/main/java/com/stardust/autojs/runtime/ScriptRuntime.java +++ b/autojs/src/main/java/com/stardust/autojs/runtime/ScriptRuntime.java @@ -41,6 +41,7 @@ public class ScriptRuntime extends AbstractScriptRuntime { private AccessibilityBridge mAccessibilityBridge; private Supplier mShellSupplier; private ScreenCaptureRequester mScreenCaptureRequester; + private AppUtils mAppUtils; public Builder() { @@ -71,6 +72,11 @@ public class ScriptRuntime extends AbstractScriptRuntime { return this; } + public Builder setAppUtils(AppUtils appUtils) { + mAppUtils = appUtils; + return this; + } + public ScriptRuntime build() { return new ScriptRuntime(this); } @@ -86,7 +92,7 @@ public class ScriptRuntime extends AbstractScriptRuntime { protected ScriptRuntime(Builder builder) { - super(builder.mUiHandler.getContext(), builder.mConsole, builder.mAccessibilityBridge, builder.mScreenCaptureRequester); + super(builder.mUiHandler.getContext(), builder.mConsole, builder.mAccessibilityBridge, builder.mAppUtils, builder.mScreenCaptureRequester); mAccessibilityBridge = builder.mAccessibilityBridge; mUiHandler = builder.mUiHandler; mShellSupplier = builder.mShellSupplier; diff --git a/autojs/src/main/java/com/stardust/autojs/runtime/api/AppUtils.java b/autojs/src/main/java/com/stardust/autojs/runtime/api/AppUtils.java index 88ab7520..28b7e5e5 100644 --- a/autojs/src/main/java/com/stardust/autojs/runtime/api/AppUtils.java +++ b/autojs/src/main/java/com/stardust/autojs/runtime/api/AppUtils.java @@ -7,6 +7,7 @@ import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.net.Uri; import android.support.annotation.Nullable; +import android.util.Log; import com.stardust.autojs.runtime.ScriptInterface; import com.stardust.util.IntentUtil; @@ -21,7 +22,7 @@ import java.util.List; public class AppUtils { private Context mContext; - private WeakReference mCurrentActivity; + private volatile WeakReference mCurrentActivity = new WeakReference<>(null); public AppUtils(Context context) { mContext = context; @@ -64,6 +65,7 @@ public class AppUtils { @Nullable public Activity getCurrentActivity() { + Log.d("App", "getCurrentActivity: " + mCurrentActivity.get()); return mCurrentActivity.get(); } @@ -75,5 +77,6 @@ public class AppUtils { public void setCurrentActivity(Activity currentActivity) { mCurrentActivity = new WeakReference<>(currentActivity); + Log.d("App", "setCurrentActivity: " + currentActivity); } } diff --git a/autojs/src/main/java/com/stardust/autojs/runtime/api/UiSelector.java b/autojs/src/main/java/com/stardust/autojs/runtime/api/UiSelector.java index 5287963d..6bf3ea40 100644 --- a/autojs/src/main/java/com/stardust/autojs/runtime/api/UiSelector.java +++ b/autojs/src/main/java/com/stardust/autojs/runtime/api/UiSelector.java @@ -118,13 +118,18 @@ public class UiSelector extends UiGlobalSelector { @NonNull public UiObjectCollection untilFind() { UiObjectCollection uiObjectCollection; - do { + uiObjectCollection = find(); + while (uiObjectCollection.empty()) { if (Thread.currentThread().isInterrupted()) { - Log.d(TAG, "Thread isInterrupted"); + throw new ScriptInterruptedException(); + } + try { + Thread.sleep(50); + } catch (InterruptedException e) { throw new ScriptInterruptedException(); } uiObjectCollection = find(); - } while (uiObjectCollection.empty()); + } return uiObjectCollection; } diff --git a/autojs/src/main/java/com/stardust/autojs/runtime/api/image/ColorDetector.java b/autojs/src/main/java/com/stardust/autojs/runtime/api/image/ColorDetector.java index 539511b1..4a116eb9 100644 --- a/autojs/src/main/java/com/stardust/autojs/runtime/api/image/ColorDetector.java +++ b/autojs/src/main/java/com/stardust/autojs/runtime/api/image/ColorDetector.java @@ -1,65 +1,72 @@ package com.stardust.autojs.runtime.api.image; +import android.graphics.Color; + +import java.util.Comparator; + /** * Created by Stardust on 2017/5/20. */ public interface ColorDetector { - boolean detectsColor(int color); + boolean detectsColor(int red, int green, int blue); abstract class AbstractColorDetector implements ColorDetector { protected final int mColor; + protected final int mR, mG, mB; public AbstractColorDetector(int color) { mColor = color; + mR = Color.red(color); + mG = Color.green(color); + mB = Color.blue(color); } } - class EqualityDetector implements ColorDetector { + class EqualityDetector extends AbstractColorDetector { - private final int mColor; public EqualityDetector(int color) { - mColor = color & 0xffffff; + super(color); } @Override - public boolean detectsColor(int color) { - return mColor == (color & 0xffffff); + public boolean detectsColor(int red, int green, int blue) { + return mR == red && mG == green && mB == blue; } } class DifferenceDetector extends AbstractColorDetector { - private final int mThreshold; + private final int mRThreshold, mGThreshold, mBThreshold; public DifferenceDetector(int color, int threshold) { super(color); - mThreshold = threshold; + mRThreshold = Color.red(threshold); + mGThreshold = Color.green(threshold); + mBThreshold = Color.blue(threshold); } @Override - public boolean detectsColor(int color) { - return Math.abs(mColor - color) <= mThreshold; + public boolean detectsColor(int R, int G, int B) { + return Math.abs(R - mR) <= mRThreshold && Math.abs(G - mG) <= mGThreshold && + Math.abs(B - mB) <= mBThreshold; } } class RDistanceDetector extends AbstractColorDetector { - private final int mR; private final int mThreshold; public RDistanceDetector(int color, int threshold) { super(color); mThreshold = threshold; - mR = (color & 0xff0000) >> 16; } @Override - public boolean detectsColor(int color) { - int R = (color & 0xff0000) >> 16; + public boolean detectsColor(int R, int G, int B) { return Math.abs(mR - R) <= mThreshold; } } @@ -67,21 +74,17 @@ public interface ColorDetector { class RGBDistanceDetector extends AbstractColorDetector { private final int mThreshold; - private final int mR, mG, mB; public RGBDistanceDetector(int color, int threshold) { super(color); - mR = (color & 0xff0000) >> 16; - mG = (color & 0x00ff00) >> 8; - mB = color & 0xff; mThreshold = threshold * threshold; } @Override - public boolean detectsColor(int color) { - int dR = ((color & 0xff0000) >> 16) - mR; - int dG = ((color & 0x00ff00) >> 8) - mG; - int dB = (color & 0xff) - mB; + public boolean detectsColor(int R, int G, int B) { + int dR = R - mR; + int dG = G - mG; + int dB = B - mB; int d = dR * dR + dG * dG + dB * dB; return d <= mThreshold; } @@ -101,11 +104,10 @@ public interface ColorDetector { } @Override - public boolean detectsColor(int color) { - int R = (color & 0xff0000) >> 16; + public boolean detectsColor(int R, int G, int B) { int dR = R - mR; - int dG = ((color & 0x00ff00) >> 8) - mG; - int dB = (color & 0xff) - mB; + int dG = G - mG; + int dB = B - mB; double meanR = (mR + R) / 2; double weightR = 2 + meanR / 256; double weightG = 4.0; @@ -121,19 +123,16 @@ public interface ColorDetector { public HDistanceDetector(int color, int threshold) { super(color); - mH = getH(color); + mH = getH(mR, mG, mB); mThreshold = threshold; } @Override - public boolean detectsColor(int color) { - return Math.abs(mH - getH(color)) <= mThreshold; + public boolean detectsColor(int R, int G, int B) { + return Math.abs(mH - getH(R, G, B)) <= mThreshold; } - private static int getH(int color) { - int R = (color & 0xff0000) >> 16; - int G = (color & 0x00ff00) >> 8; - int B = color & 0xff; + private static int getH(int R, int G, int B) { int max, min, H; if (R > G) { min = Math.min(G, B); @@ -161,24 +160,21 @@ public interface ColorDetector { public HSDistanceDetector(int color, int threshold) { super(color); - long HS = getHS(color); + long HS = getHS(mR, mG, mB); mH = (int) (HS & 0xffffffffL); mS = (int) ((HS >> 32) & 0xffffffffL); mThreshold = threshold * threshold; } @Override - public boolean detectsColor(int color) { - long hs = getHS(color); + public boolean detectsColor(int R, int G, int B) { + long hs = getHS(R, G, B); int dH = (int) (hs & 0xffffffffL) - mH; int dS = (int) ((hs >> 32) & 0xffffffffL) - mS; return dH * dH + dS * dS <= mThreshold; } - private static long getHS(int color) { - int R = (color & 0xff0000) >> 16; - int G = (color & 0x00ff00) >> 8; - int B = color & 0xff; + private static long getHS(int R, int G, int B) { int max, min, H; if (R > G) { min = Math.min(G, B); diff --git a/autojs/src/main/java/com/stardust/autojs/runtime/api/image/ColorFinder.java b/autojs/src/main/java/com/stardust/autojs/runtime/api/image/ColorFinder.java index a285ac8c..5512187d 100644 --- a/autojs/src/main/java/com/stardust/autojs/runtime/api/image/ColorFinder.java +++ b/autojs/src/main/java/com/stardust/autojs/runtime/api/image/ColorFinder.java @@ -151,9 +151,11 @@ public class ColorFinder { public static Point findColor(ColorIterator iterator, ColorDetector detector) { Thread thread = Thread.currentThread(); - while (!thread.isInterrupted() && iterator.hasNext()) { - int c = iterator.nextColor(); - if (detector.detectsColor(c)) { + ColorIterator.Pixel pixel = new ColorIterator.Pixel(); + while (iterator.hasNext() && !thread.isInterrupted()) { + iterator.nextColor(pixel); + iterator.nextColor(pixel); + if (detector.detectsColor(pixel.red, pixel.green, pixel.blue)) { return new Point(iterator.getX(), iterator.getY()); } } @@ -206,9 +208,11 @@ public class ColorFinder { @Override public void run() { Thread thread = Thread.currentThread(); + ColorIterator.Pixel pixel = new ColorIterator.Pixel(); while (mResultBox.isNull() && mColorIterator.hasNext() && !thread.isInterrupted()) { - int c = mColorIterator.nextColor(); - if (mColorDetector.detectsColor(c)) { + mColorIterator.nextColor(pixel); + mColorIterator.nextColor(pixel); + if (mColorDetector.detectsColor(pixel.red, pixel.green, pixel.blue)) { mResultBox.set(new Point(mColorIterator.getX(), mColorIterator.getY())); break; } @@ -234,9 +238,10 @@ public class ColorFinder { @Override public void run() { Thread thread = Thread.currentThread(); + ColorIterator.Pixel pixel = new ColorIterator.Pixel(); while (mColorIterator.hasNext() && !thread.isInterrupted()) { - int c = mColorIterator.nextColor(); - if (mColorDetector.detectsColor(c)) { + mColorIterator.nextColor(pixel); + if (mColorDetector.detectsColor(pixel.red, pixel.green, pixel.blue)) { mResult.add(new Point(mColorIterator.getX(), mColorIterator.getY())); } } diff --git a/autojs/src/main/java/com/stardust/autojs/runtime/api/image/ColorIterator.java b/autojs/src/main/java/com/stardust/autojs/runtime/api/image/ColorIterator.java index a61c4d9e..f35951a0 100644 --- a/autojs/src/main/java/com/stardust/autojs/runtime/api/image/ColorIterator.java +++ b/autojs/src/main/java/com/stardust/autojs/runtime/api/image/ColorIterator.java @@ -12,9 +12,15 @@ import java.nio.ByteBuffer; public interface ColorIterator { + class Pixel { + int red; + int green; + int blue; + } + boolean hasNext(); - int nextColor(); + void nextColor(Pixel pixel); int getX(); @@ -94,7 +100,7 @@ public interface ColorIterator { } @Override - public int nextColor() { + public void nextColor(Pixel pixel) { if (mX == mWidth - 1) { skip(mSkipPerRow); mX = 0; @@ -102,11 +108,9 @@ public interface ColorIterator { } else { mX++; } - int c = (mByteBuffer.get() & 0xff) << 16; - c |= (mByteBuffer.get() & 0xff) << 8; - c |= (mByteBuffer.get() & 0xff); - c |= (mByteBuffer.get() & 0xff) << 24; - return c; + pixel.red = mByteBuffer.get() & 0xff; + pixel.green = mByteBuffer.get() & 0xff; + pixel.blue = mByteBuffer.get() & 0xff; } } @@ -145,7 +149,7 @@ public interface ColorIterator { } @Override - public int nextColor() { + public void nextColor(Pixel pixel) { int c = mByteBuffer.getInt(); skip(mNextStepSkip); mStepCount++; @@ -168,7 +172,6 @@ public interface ColorIterator { break; } } - return c; } @Override diff --git a/automator/src/main/java/com/stardust/view/accessibility/AccessibilityService.java b/automator/src/main/java/com/stardust/view/accessibility/AccessibilityService.java index 8b1e26e0..f95d6d31 100644 --- a/automator/src/main/java/com/stardust/view/accessibility/AccessibilityService.java +++ b/automator/src/main/java/com/stardust/view/accessibility/AccessibilityService.java @@ -1,5 +1,7 @@ package com.stardust.view.accessibility; +import android.support.annotation.CallSuper; +import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityNodeInfo; import java.util.concurrent.CopyOnWriteArrayList; @@ -16,15 +18,21 @@ public abstract class AccessibilityService extends android.accessibilityservice. } private CopyOnWriteArrayList mNotificationCallbacks = new CopyOnWriteArrayList<>(); + private AccessibilityNodeInfo mRootInActiveWindow; + @CallSuper @Override - - public AccessibilityNodeInfo getRootInActiveWindow() { - try { - return super.getRootInActiveWindow(); - } catch (Exception ignored) { - return null; + public void onAccessibilityEvent(AccessibilityEvent event) { + if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED + || event.getEventType() == AccessibilityEvent.TYPE_VIEW_HOVER_ENTER + || event.getEventType() == AccessibilityEvent.TYPE_VIEW_HOVER_EXIT) { + mRootInActiveWindow = super.getRootInActiveWindow(); } } + @Override + public AccessibilityNodeInfo getRootInActiveWindow() { + return mRootInActiveWindow; + } + }