Commit 5e5ecf81 authored by Administrator's avatar Administrator

Merge branch 'master' of git.virjar.com:ratel/ratelextension

parents e0c5c163 2f43b8e2
package com.virjar.ratel.api.extension;
import android.support.annotation.NonNull;
import android.util.Log;
import com.virjar.ratel.api.RatelToolKit;
import com.virjar.ratel.api.rposed.RposedBridge;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.BlockingDeque;
import java.util.concurrent.LinkedBlockingDeque;
import external.org.apache.commons.io.IOUtils;
public class FileLogger {
//异步任务队列,最多2048个,超过后忽略日志
private static BlockingDeque<LogMessage> blockingDeque = new LinkedBlockingDeque<>(2048);
private static Thread syncLogThread = null;
private static OutputStream outputStream = null;
private static byte[] newLine = System.getProperty("line.separator", "\n").getBytes();
public synchronized static void startRecord(File baseDir) {
if (syncLogThread != null) {
return;
}
RposedBridge.log("file start");
File dir = new File(baseDir, "file_log");
String processName = RatelToolKit.processName;
if (!dir.exists()) {
boolean create = dir.mkdirs();
RposedBridge.log("create file : " + create + ",processName=" + processName);
}
processName = processName.replace(":", "_");
File filename = new File(dir, processName + "__" + System.currentTimeMillis() + ".txt");
RposedBridge.log("filename:" + filename.getAbsolutePath());
try {
if (filename.createNewFile()) {
outputStream = new FileOutputStream(filename, true);
} else {
RposedBridge.log("failed to create log file :" + filename.getAbsolutePath());
}
} catch (IOException e) {
e.printStackTrace();
return;
}
RposedBridge.log("start thread");
syncLogThread = new Thread() {
@Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
try {
blockingDeque.take().handle(outputStream);
outputStream.write(newLine);
//多增加两次回车换行,分割各个报文
outputStream.write(newLine);
outputStream.write(newLine);
outputStream.flush();
} catch (InterruptedException e) {
blockingDeque.clear();
return;
} catch (Exception e) {
e.printStackTrace();
}
}
}
};
outLog("\n<=========================================================>\n");
syncLogThread.setDaemon(true);
syncLogThread.start();
}
public synchronized static void stopRecord() {
if (syncLogThread == null) {
return;
}
if (syncLogThread.isInterrupted()) {
syncLogThread = null;
return;
}
syncLogThread.interrupt();
syncLogThread = null;
IOUtils.closeQuietly(outputStream);
outputStream = null;
blockingDeque.clear();
}
public static boolean isComponentStarted() {
return syncLogThread != null;
}
public static void outLog(final String message) {
if (!isComponentStarted()) {
return;
}
blockingDeque.offer(new LogMessage() {
@Override
public void handle(OutputStream outputStream) throws IOException {
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream, StandardCharsets.UTF_8);
outputStreamWriter.write(message);
outputStreamWriter.flush();
}
});
}
public static void outLog(final InputStream inputStream) {
if (!isComponentStarted()) {
return;
}
blockingDeque.offer(new LogMessage() {
@Override
public void handle(OutputStream outputStream) throws IOException {
IOUtils.copy(inputStream, outputStream);
outputStream.flush();
}
});
}
public static void outLog(final byte[] data) {
if (!isComponentStarted()) {
return;
}
blockingDeque.offer(new LogMessage() {
@Override
public void handle(OutputStream outputStream) throws IOException {
outputStream.write(data);
}
});
}
public static void outLog(final String tag, final String message) {
if (!isComponentStarted()) {
return;
}
blockingDeque.offer(new LogMessage() {
@Override
public void handle(OutputStream outputStream) throws IOException {
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream, StandardCharsets.UTF_8);
outputStreamWriter.append(tag);
outputStreamWriter.append(message);
outputStreamWriter.flush();
}
});
}
public static void outLog(final String tag, final InputStream inputStream) {
if (!isComponentStarted()) {
return;
}
blockingDeque.offer(new LogMessage() {
@Override
public void handle(OutputStream outputStream) throws IOException {
outputStream.write(tag.getBytes());
IOUtils.copy(inputStream, outputStream);
}
});
}
public static void outLog(final String tag, final byte[] data) {
if (!isComponentStarted()) {
return;
}
blockingDeque.offer(new LogMessage() {
@Override
public void handle(OutputStream outputStream) throws IOException {
outputStream.write(tag.getBytes());
outputStream.write(data);
}
});
}
public static void outLog(final LogMessage logMessage) {
if (!isComponentStarted()) {
return;
}
blockingDeque.offer(new LogMessage() {
@Override
public void handle(final OutputStream outputStream) throws IOException {
logMessage.handle(new OutputStream() {
@Override
public void write(int b) throws IOException {
outputStream.write(b);
}
@Override
public void write(@NonNull byte[] b) throws IOException {
outputStream.write(b);
}
@Override
public void write(@NonNull byte[] b, int off, int len) throws IOException {
outputStream.write(b, off, len);
}
@Override
public void flush() throws IOException {
outputStream.flush();
}
@Override
public void close() throws IOException {
}
});
}
});
}
public interface LogMessage {
void handle(OutputStream outputStream) throws IOException;
}
public static void outTrack(String append) {
String msg = append + getTrack();
outLog(msg);
}
public static String getTrack() {
return getTrack(new Throwable());
}
public static String getOwnerThreadTrack() {
return getTrack(new Throwable());
}
public static String getTrack(Throwable e) {
StringBuilder msg = new StringBuilder("\n=============>\n");
while (e != null) {
StackTraceElement[] ste = e.getStackTrace();
for (StackTraceElement stackTraceElement : ste) {
msg.append(stackTraceElement.getClassName()).append(".").append(stackTraceElement.getMethodName()).append(":").append(stackTraceElement.getLineNumber()).append("\n");
}
e = e.getCause();
if (e != null) {
msg.append("cause:").append(e.getMessage()).append("\n\n");
}
}
msg.append("<================\n");
return msg.toString();
}
/**
* 分段打印出较长log文本
*
* @param log 原log文本
* @param showCount 规定每段显示的长度(最好不要超过eclipse限制长度)
*/
public static void showLogCompletion(String tag, String log, int showCount) {
if (log.length() > showCount) {
String show = log.substring(0, showCount);
// System.out.println(show);
Log.e(tag, show + "");
if ((log.length() - showCount) > showCount) {//剩下的文本还是大于规定长度
String partLog = log.substring(showCount, log.length());
showLogCompletion(tag, partLog, showCount);
} else {
String surplusLog = log.substring(showCount, log.length());
// System.out.println(surplusLog);
Log.e(tag, surplusLog + "");
}
} else {
// System.out.println(log);
Log.e(tag, log + "");
}
}
}
......@@ -99,21 +99,21 @@ public class SwipeUtils {
private static void dealSimulateScroll(ViewImage object, float startX, float startY, float endX, float endY, long duration, int period) {
if (isScrolling) {
Log.i(SuperAppium.TAG, "score task is running..");
Log.i(SuperAppium.TAG, "scroll task is running..");
return;
}
isScrolling = true;
Handler handler = new ViewHandler(object);
//重置相对偏移
int[] loca = new int[2];
object.rootViewImage().getOriginView().getLocationOnScreen(loca);
startX -= loca[0];
endX -= loca[0];
startY -= loca[1];
endY -= loca[1];
// //重置相对偏移
// int[] loca = new int[2];
// object.rootViewImage().getOriginView().getLocationOnScreen(loca);
//
// startX -= loca[0];
// endX -= loca[0];
//
// startY -= loca[1];
// endY -= loca[1];
object.dispatchPointerEvent(genFingerEvent(MotionEvent.ACTION_DOWN, startX, startY));
......@@ -123,6 +123,7 @@ public class SwipeUtils {
private static MotionEvent genFingerEvent(int action, float x, float y) {
//Log.i("HD_HOOK", "genFingerEvent action: " + action + " point:(" + x + " , " + y + ")");
long downTime = SystemClock.uptimeMillis();
long eventTime = SystemClock.uptimeMillis();
......@@ -153,14 +154,25 @@ public class SwipeUtils {
public void handleMessage(Message msg) {
ViewImage theView = mView.get();
if (theView == null) {
Log.e(SuperAppium.TAG, "scroll view has bean destroyed");
isScrolling = false;
return;
}
GestureBean bean = (GestureBean) msg.obj;
long count = bean.count;
if (count >= bean.totalCount) {
theView.dispatchInputEvent(genFingerEvent(MotionEvent.ACTION_UP, bean.endX, bean.endY));
theView.dispatchPointerEvent(genFingerEvent(MotionEvent.ACTION_MOVE, bean.endX, bean.endY));
new Handler(Looper.myLooper()).post(
new Runnable() {
@Override
public void run() {
theView.dispatchPointerEvent(genFingerEvent(MotionEvent.ACTION_UP, bean.endX, bean.endY));
}
}
);
isScrolling = false;
} else {
float x = bean.startX + bean.ratioX * count;
float y = bean.startY + bean.ratioY * count;
......@@ -183,7 +195,17 @@ public class SwipeUtils {
}
if (upEarly) {
theView.dispatchInputEvent(genFingerEvent(MotionEvent.ACTION_UP, x, y));
theView.dispatchPointerEvent(genFingerEvent(MotionEvent.ACTION_MOVE, x, y));
float finalX = x;
float finalY = y;
new Handler(Looper.myLooper()).post(
new Runnable() {
@Override
public void run() {
theView.dispatchPointerEvent(genFingerEvent(MotionEvent.ACTION_UP, finalX, finalY));
}
}
);
isScrolling = false;
return;
}
......
......@@ -4,10 +4,12 @@ import android.annotation.SuppressLint;
import android.os.Handler;
import android.os.Looper;
import android.os.SystemClock;
import android.util.Log;
import android.view.InputEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.EditorInfo;
import android.webkit.WebView;
import android.widget.AdapterView;
import android.widget.EditText;
......@@ -285,6 +287,8 @@ public class ViewImage {
EditText editText = (EditText) originView;
editText.getText().clear();
editText.setText(content);
//触发焦点到下一个输入框
editText.onEditorAction(EditorInfo.IME_ACTION_NEXT);
return true;
}
......@@ -345,6 +349,7 @@ public class ViewImage {
View rootView = rootViewImage().getOriginView();
final Object mViewRootImpl = RposedHelpers.callMethod(rootView, "getViewRootImpl");
if (mViewRootImpl == null) {
Log.w(SuperAppium.TAG, "can not find RootViewImpl to dispatch event");
return false;
}
RposedHelpers.callMethod(mViewRootImpl, "dispatchInputEvent", inputEvent);
......@@ -394,15 +399,62 @@ public class ViewImage {
int toX = (int) (fromX + viewWidth * (ThreadLocalRandom.current().nextDouble(0.1)));
int fromY = (int) (locs[1] + viewHeight * ThreadLocalRandom.current().nextDouble(0.1));
if (fromY < 2) {
fromY = 2;
int fromY, toY;
if (height > 0) {
fromY = (int) (locs[1] + viewHeight * ThreadLocalRandom.current().nextDouble(0.1));
if (fromY < 2) {
fromY = 2;
}
toY = fromY + height;
} else {
fromY = (int) (locs[1] + viewHeight * (ThreadLocalRandom.current().nextDouble(0.1) + 0.9));
toY = fromY + height;
if (toY < 2) {
toY = 2;
}
}
int toY = fromY + height;
SwipeUtils.simulateScroll(this, fromX, fromY, toX, toY, 400, 50);
}
/**
* 向右滑动
*
* @param width 滑动宽度,如果为负数,则向左滑动
*/
@SuppressLint("NewApi")
public void swipeRight(int width) {
int[] locs = new int[2];
originView.getLocationOnScreen(locs);
int viewWidth = originView.getWidth();
int viewHeight = originView.getHeight();
int fromY = (int) (locs[1] + viewHeight * (ThreadLocalRandom.current().nextDouble(0.05) - 0.025 + 0.5));
if (fromY < 2) {
fromY = 2;
}
int toY = (int) (fromY + viewHeight * (ThreadLocalRandom.current().nextDouble(0.008)));
int fromX, toX;
if (width > 0) {
fromX = (int) (locs[0] + viewWidth * ThreadLocalRandom.current().nextDouble(0.1));
if (fromX < 2) {
fromX = 2;
}
toX = fromX + width;
} else {
fromX = (int) (locs[0] + viewWidth * (ThreadLocalRandom.current().nextDouble(0.1) + 0.9));
toX = fromX + width;
if (toX < 2) {
toX = 2;
}
}
// Log.i(SuperAppium.TAG, "location on screen: (" + locs[0] + "," + locs[1] + ") from loc:("
// + fromX + "," + fromY + ") to loc:(" + toX + "," + toY + ") with and height: (" + viewWidth + "," + viewHeight + ")");
SwipeUtils.simulateScroll(this, fromX, fromY, toX, toY, 300, 50);
}
private MotionEvent genMotionEvent(int action, float[] point) {
long downTime = SystemClock.uptimeMillis();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment