opt: layout inspector toast

This commit is contained in:
hyb1996
2018-01-24 20:54:46 +08:00
parent 25a9a6b870
commit d6c9fe4f09
6 changed files with 62 additions and 26 deletions

View File

@@ -31,9 +31,12 @@ import com.stardust.scriptdroid.ui.main.scripts.ScriptListView;
import com.stardust.theme.dialog.ThemeColorMaterialDialogBuilder; import com.stardust.theme.dialog.ThemeColorMaterialDialogBuilder;
import com.stardust.util.ClipboardUtil; import com.stardust.util.ClipboardUtil;
import com.stardust.view.accessibility.LayoutInspector; import com.stardust.view.accessibility.LayoutInspector;
import com.stardust.view.accessibility.NodeInfo;
import com.stericson.RootShell.RootShell; import com.stericson.RootShell.RootShell;
import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.EventBus;
import org.jdeferred.Deferred;
import org.jdeferred.impl.DeferredObject;
import butterknife.ButterKnife; import butterknife.ButterKnife;
import butterknife.OnClick; import butterknife.OnClick;
@@ -43,7 +46,8 @@ import butterknife.Optional;
* Created by Stardust on 2017/10/18. * Created by Stardust on 2017/10/18.
*/ */
public class CircularMenu implements Recorder.OnStateChangedListener { public class CircularMenu implements Recorder.OnStateChangedListener, LayoutInspector.CaptureAvailableListener {
public static class StateChangeEvent { public static class StateChangeEvent {
private int currentState; private int currentState;
@@ -76,6 +80,7 @@ public class CircularMenu implements Recorder.OnStateChangedListener {
private GlobalActionRecorder mRecorder; private GlobalActionRecorder mRecorder;
private MaterialDialog mSettingsDialog; private MaterialDialog mSettingsDialog;
private String mRunningPackage, mRunningActivity; private String mRunningPackage, mRunningActivity;
private Deferred<NodeInfo, Void, Void> mCaptureDeferred;
public CircularMenu(Context context) { public CircularMenu(Context context) {
mContext = new ContextThemeWrapper(context, R.style.AppTheme); mContext = new ContextThemeWrapper(context, R.style.AppTheme);
@@ -83,6 +88,7 @@ public class CircularMenu implements Recorder.OnStateChangedListener {
setupListeners(); setupListeners();
mRecorder = GlobalActionRecorder.getSingleton(context); mRecorder = GlobalActionRecorder.getSingleton(context);
mRecorder.addOnStateChangedListener(this); mRecorder.addOnStateChangedListener(this);
AutoJs.getInstance().getLayoutInspector().addCaptureAvailableListener(this);
} }
private void setupListeners() { private void setupListeners() {
@@ -92,6 +98,7 @@ public class CircularMenu implements Recorder.OnStateChangedListener {
} else if (mWindow.isExpanded()) { } else if (mWindow.isExpanded()) {
mWindow.collapse(); mWindow.collapse();
} else { } else {
mCaptureDeferred = new DeferredObject<>();
AutoJs.getInstance().getLayoutInspector().captureCurrentWindow(); AutoJs.getInstance().getLayoutInspector().captureCurrentWindow();
mWindow.expand(); mWindow.expand();
} }
@@ -182,12 +189,14 @@ public class CircularMenu implements Recorder.OnStateChangedListener {
if (!ensureCapture()) { if (!ensureCapture()) {
return; return;
} }
LayoutBoundsFloatyWindow window = new LayoutBoundsFloatyWindow( mCaptureDeferred.promise()
AutoJs.getInstance().getLayoutInspector().getCapture() .done(capture -> {
); LayoutBoundsFloatyWindow window = new LayoutBoundsFloatyWindow(capture);
FloatyService.addWindow(window); mActionViewIcon.post(() -> FloatyService.addWindow(window));
});
} }
@Optional @Optional
@OnClick(R.id.layout_hierarchy) @OnClick(R.id.layout_hierarchy)
void showLayoutHierarchy() { void showLayoutHierarchy() {
@@ -195,20 +204,28 @@ public class CircularMenu implements Recorder.OnStateChangedListener {
if (!ensureCapture()) { if (!ensureCapture()) {
return; return;
} }
LayoutHierarchyFloatyWindow window = new LayoutHierarchyFloatyWindow( mCaptureDeferred.promise()
AutoJs.getInstance().getLayoutInspector().getCapture() .done(capture -> {
); LayoutHierarchyFloatyWindow window = new LayoutHierarchyFloatyWindow(capture);
FloatyService.addWindow(window); mActionViewIcon.post(() -> FloatyService.addWindow(window));
});
}
@Override
public void onCaptureAvailable(NodeInfo capture) {
mCaptureDeferred.resolve(capture);
} }
private boolean ensureCapture() { private boolean ensureCapture() {
LayoutInspector inspector = AutoJs.getInstance().getLayoutInspector(); LayoutInspector inspector = AutoJs.getInstance().getLayoutInspector();
if (inspector.isDumping()) { if (inspector.isDumping()) {
Toast.makeText(mContext, R.string.text_layout_inspector_is_dumping, Toast.LENGTH_SHORT).show(); Toast.makeText(mContext, R.string.text_layout_inspector_is_dumping, Toast.LENGTH_SHORT).show();
return false; return true;
} }
if (AccessibilityService.getInstance() == null) { if (AccessibilityService.getInstance() == null) {
Toast.makeText(mContext, R.string.text_no_accessibility_permission_to_capture, Toast.LENGTH_SHORT).show(); Toast.makeText(mContext, R.string.text_no_accessibility_permission_to_capture, Toast.LENGTH_SHORT).show();
AccessibilityServiceTool.goToAccessibilitySetting();
return false; return false;
} }
if (inspector.getCapture() == null) { if (inspector.getCapture() == null) {
@@ -296,6 +313,7 @@ public class CircularMenu implements Recorder.OnStateChangedListener {
mState = STATE_CLOSED; mState = STATE_CLOSED;
} }
mRecorder.removeOnStateChangedListener(this); mRecorder.removeOnStateChangedListener(this);
AutoJs.getInstance().getLayoutInspector().removeCaptureAvailableListener(this);
} }

View File

@@ -135,7 +135,7 @@
<string name="text_guard_mode">保护模式</string> <string name="text_guard_mode">保护模式</string>
<string name="summary_guard_mode">在本软件界面无法运行自动操作命令以免误触</string> <string name="summary_guard_mode">在本软件界面无法运行自动操作命令以免误触</string>
<string name="key_guard_mode">key_guard_mode</string> <string name="key_guard_mode">key_guard_mode</string>
<string name="text_layout_inspector_is_dumping">布局分析中,请稍后点击</string> <string name="text_layout_inspector_is_dumping">布局分析中</string>
<string name="text_force_stop">强制停止</string> <string name="text_force_stop">强制停止</string>
<string name="text_execution_finished" formatted="false">\n------------\n[%s]运行结束,用时%f秒</string> <string name="text_execution_finished" formatted="false">\n------------\n[%s]运行结束,用时%f秒</string>
<string name="text_again"></string> <string name="text_again"></string>

View File

@@ -13,7 +13,7 @@
> >
<activity <activity
android:name=".execution.ScriptExecuteActivity" android:name=".execution.ScriptExecuteActivity"
android:theme="@style/Theme.AppCompat.Light.NoActionBar"/> android:theme="@style/AppTheme"/>
<activity <activity
android:name="com.stardust.autojs.core.image.ScreenCaptureRequestActivity" android:name="com.stardust.autojs.core.image.ScreenCaptureRequestActivity"
@@ -22,7 +22,6 @@
android:theme="@style/AppTheme.Transparent"/> android:theme="@style/AppTheme.Transparent"/>
</application> </application>
</manifest> </manifest>

View File

@@ -50,7 +50,6 @@ public class RhinoJavaScriptEngine extends JavaScriptEngine {
mAndroidContext = context; mAndroidContext = context;
mContext = createContext(); mContext = createContext();
mScriptable = createScope(mContext); mScriptable = createScope(mContext);
} }
@Override @Override

View File

@@ -8,6 +8,8 @@ import android.view.accessibility.AccessibilityNodeInfo;
import com.stardust.view.accessibility.AccessibilityService; import com.stardust.view.accessibility.AccessibilityService;
import com.stardust.util.UnderuseExecutors; import com.stardust.util.UnderuseExecutors;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
@@ -17,29 +19,45 @@ import java.util.concurrent.Executors;
public class LayoutInspector { public class LayoutInspector {
public interface CaptureAvailableListener {
void onCaptureAvailable(NodeInfo capture);
}
private static final String LOG_TAG = LayoutInspector.class.getSimpleName(); private static final String LOG_TAG = LayoutInspector.class.getSimpleName();
private volatile NodeInfo mCapture; private volatile NodeInfo mCapture;
private volatile boolean mDumping = false; private volatile boolean mDumping = false;
private Executor mExecutor = Executors.newSingleThreadExecutor(); private Executor mExecutor = Executors.newSingleThreadExecutor();
private CopyOnWriteArrayList<CaptureAvailableListener> mCaptureAvailableListeners = new CopyOnWriteArrayList<>();
public void captureCurrentWindow() { public void captureCurrentWindow() {
AccessibilityService service = AccessibilityService.getInstance(); AccessibilityService service = AccessibilityService.getInstance();
if (service == null) { if (service == null) {
Log.d(LOG_TAG, "captureCurrentWindow: service = null"); Log.d(LOG_TAG, "captureCurrentWindow: service = null");
mCapture = null; mCapture = null;
} else { return;
final AccessibilityNodeInfo root = getRootInActiveWindow(service);
if (root == null) {
Log.d(LOG_TAG, "captureCurrentWindow: root = null");
mCapture = null;
} else {
mExecutor.execute(() -> {
mDumping = true;
mCapture = NodeInfo.capture(root);
mDumping = false;
});
}
} }
final AccessibilityNodeInfo root = getRootInActiveWindow(service);
if (root == null) {
Log.d(LOG_TAG, "captureCurrentWindow: root = null");
mCapture = null;
return;
}
mExecutor.execute(() -> {
mDumping = true;
mCapture = NodeInfo.capture(root);
mDumping = false;
for (CaptureAvailableListener l : mCaptureAvailableListeners) {
l.onCaptureAvailable(mCapture);
}
});
}
public void addCaptureAvailableListener(CaptureAvailableListener l){
mCaptureAvailableListeners.add(l);
}
public boolean removeCaptureAvailableListener(CaptureAvailableListener l){
return mCaptureAvailableListeners.remove(l);
} }
private AccessibilityNodeInfo getRootInActiveWindow(AccessibilityService service) { private AccessibilityNodeInfo getRootInActiveWindow(AccessibilityService service) {

View File

@@ -8,6 +8,8 @@ import com.stardust.autojs.project.ProjectConfig;
import com.stardust.autojs.script.JavaScriptFileSource; import com.stardust.autojs.script.JavaScriptFileSource;
import com.stardust.pio.PFiles; import com.stardust.pio.PFiles;
import org.mozilla.javascript.optimizer.ClassCompiler;
import java.io.File; import java.io.File;
/** /**