wtf
This commit is contained in:
@@ -38,6 +38,7 @@ import com.stardust.util.Supplier;
|
|||||||
import com.stardust.util.UiHandler;
|
import com.stardust.util.UiHandler;
|
||||||
import com.stardust.view.accessibility.AccessibilityInfoProvider;
|
import com.stardust.view.accessibility.AccessibilityInfoProvider;
|
||||||
import com.stardust.autojs.core.record.accessibility.AccessibilityActionRecorder;
|
import com.stardust.autojs.core.record.accessibility.AccessibilityActionRecorder;
|
||||||
|
import com.stardust.view.accessibility.AccessibilityNotificationObserver;
|
||||||
import com.stardust.view.accessibility.AccessibilityService;
|
import com.stardust.view.accessibility.AccessibilityService;
|
||||||
import com.stardust.scriptdroid.tool.AccessibilityServiceTool;
|
import com.stardust.scriptdroid.tool.AccessibilityServiceTool;
|
||||||
import com.stardust.view.accessibility.LayoutInspector;
|
import com.stardust.view.accessibility.LayoutInspector;
|
||||||
@@ -61,7 +62,7 @@ public class AutoJs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private final AccessibilityActionRecorder mAccessibilityActionRecorder = new AccessibilityActionRecorder();
|
private final AccessibilityActionRecorder mAccessibilityActionRecorder = new AccessibilityActionRecorder();
|
||||||
private final NotificationListener.Observer mNotificationObserver;
|
private final AccessibilityNotificationObserver mNotificationObserver;
|
||||||
private ScriptEngineManager mScriptEngineManager;
|
private ScriptEngineManager mScriptEngineManager;
|
||||||
private final LayoutInspector mLayoutInspector = new LayoutInspector();
|
private final LayoutInspector mLayoutInspector = new LayoutInspector();
|
||||||
private final Context mContext;
|
private final Context mContext;
|
||||||
@@ -85,7 +86,7 @@ public class AutoJs {
|
|||||||
return log;
|
return log;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
mNotificationObserver = new NotificationListener.Observer(context);
|
mNotificationObserver = new AccessibilityNotificationObserver(context);
|
||||||
mAccessibilityInfoProvider = new AccessibilityInfoProvider(context.getPackageManager());
|
mAccessibilityInfoProvider = new AccessibilityInfoProvider(context.getPackageManager());
|
||||||
mScriptEngineService = buildScriptEngineService();
|
mScriptEngineService = buildScriptEngineService();
|
||||||
addAccessibilityServiceDelegates();
|
addAccessibilityServiceDelegates();
|
||||||
@@ -230,7 +231,7 @@ public class AutoJs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NotificationListener.Observer getNotificationObserver() {
|
public AccessibilityNotificationObserver getNotificationObserver() {
|
||||||
return mNotificationObserver;
|
return mNotificationObserver;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ public class DevPluginService {
|
|||||||
|
|
||||||
private static DevPluginService sInstance = new DevPluginService();
|
private static DevPluginService sInstance = new DevPluginService();
|
||||||
private DevPluginClient mClient;
|
private DevPluginClient mClient;
|
||||||
private final PublishSubject<DevPluginClient.State> mConnection = PublishSubject.create();
|
private final PublishSubject<DevPluginClient.State> mConnection = PublishSubject.create();
|
||||||
|
|
||||||
public static DevPluginService getInstance() {
|
public static DevPluginService getInstance() {
|
||||||
return sInstance;
|
return sInstance;
|
||||||
@@ -23,7 +23,7 @@ public class DevPluginService {
|
|||||||
return mClient != null && mClient.getState() == DevPluginClient.State.CONNECTED;
|
return mClient != null && mClient.getState() == DevPluginClient.State.CONNECTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isDisconnected(){
|
public boolean isDisconnected() {
|
||||||
return mClient == null || mClient.getState() == DevPluginClient.State.DISCONNECTED;
|
return mClient == null || mClient.getState() == DevPluginClient.State.DISCONNECTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,7 +44,14 @@ public class DevPluginService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void connectToServer(String host) {
|
public void connectToServer(String host) {
|
||||||
mClient = new DevPluginClient(host, 1209, mConnection);
|
int port = 1209;
|
||||||
|
String ip = host;
|
||||||
|
int i = host.lastIndexOf(':');
|
||||||
|
if (i > 0 && i < host.length() - 1) {
|
||||||
|
port = Integer.parseInt(host.substring(i + 1));
|
||||||
|
ip = host.substring(0, i);
|
||||||
|
}
|
||||||
|
mClient = new DevPluginClient(ip, port, mConnection);
|
||||||
mClient.setResponseHandler(new DevPluginResponseHandler());
|
mClient.setResponseHandler(new DevPluginResponseHandler());
|
||||||
mClient.connectToServer();
|
mClient.connectToServer();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -163,45 +163,29 @@ public class EditorMenu {
|
|||||||
private void jumpToLine() {
|
private void jumpToLine() {
|
||||||
mEditor.getLineCount()
|
mEditor.getLineCount()
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.subscribe(new Consumer<Integer>() {
|
.subscribe(this::showJumpDialog);
|
||||||
@Override
|
|
||||||
public void accept(@NonNull Integer lineCount) throws Exception {
|
|
||||||
showJumpDialog(lineCount);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void showJumpDialog(final int lineCount) {
|
private void showJumpDialog(final int lineCount) {
|
||||||
String hint = "1 ~ " + lineCount;
|
String hint = "1 ~ " + lineCount;
|
||||||
new ThemeColorMaterialDialogBuilder(mContext)
|
new ThemeColorMaterialDialogBuilder(mContext)
|
||||||
.title(R.string.text_jump_to_line)
|
.title(R.string.text_jump_to_line)
|
||||||
.input(hint, "", new MaterialDialog.InputCallback() {
|
.input(hint, "", (dialog, input) -> {
|
||||||
@Override
|
int line = Integer.parseInt(input.toString());
|
||||||
public void onInput(@android.support.annotation.NonNull MaterialDialog dialog, CharSequence input) {
|
mEditor.jumpTo(line - 1, 0);
|
||||||
int line = Integer.parseInt(input.toString());
|
|
||||||
mEditor.jumpTo(line - 1, 0);
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
.inputType(InputType.TYPE_CLASS_NUMBER)
|
.inputType(InputType.TYPE_CLASS_NUMBER)
|
||||||
.show();
|
.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void showInfo() {
|
private void showInfo() {
|
||||||
Observable.zip(mEditor.getText(), mEditor.getLineCount(), new BiFunction<String, Integer, String>() {
|
Observable.zip(mEditor.getText(), mEditor.getLineCount(), (text, lineCount) -> {
|
||||||
@Override
|
String size = PFiles.getHumanReadableSize(text.length());
|
||||||
public String apply(@NonNull String text, @NonNull Integer lineCount) throws Exception {
|
return String.format(Locale.getDefault(), mContext.getString(R.string.format_editor_info),
|
||||||
String size = PFiles.getHumanReadableSize(text.length());
|
text.length(), lineCount, size);
|
||||||
return String.format(Locale.getDefault(), mContext.getString(R.string.format_editor_info),
|
|
||||||
text.length(), lineCount, size);
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.subscribe(new Consumer<String>() {
|
.subscribe(this::showInfo);
|
||||||
@Override
|
|
||||||
public void accept(@NonNull String info) throws Exception {
|
|
||||||
showInfo(info);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
package com.stardust.scriptdroid.ui.user;
|
package com.stardust.scriptdroid.ui.user;
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
|
import android.view.View;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
@@ -12,6 +12,7 @@ import com.stardust.scriptdroid.R;
|
|||||||
import com.stardust.scriptdroid.network.NodeBB;
|
import com.stardust.scriptdroid.network.NodeBB;
|
||||||
import com.stardust.scriptdroid.network.UserService;
|
import com.stardust.scriptdroid.network.UserService;
|
||||||
import com.stardust.scriptdroid.ui.BaseActivity;
|
import com.stardust.scriptdroid.ui.BaseActivity;
|
||||||
|
import com.stardust.theme.ThemeColorManager;
|
||||||
|
|
||||||
import org.androidannotations.annotations.AfterViews;
|
import org.androidannotations.annotations.AfterViews;
|
||||||
import org.androidannotations.annotations.Click;
|
import org.androidannotations.annotations.Click;
|
||||||
@@ -33,9 +34,13 @@ public class LoginActivity extends BaseActivity {
|
|||||||
@ViewById(R.id.password)
|
@ViewById(R.id.password)
|
||||||
TextView mPassword;
|
TextView mPassword;
|
||||||
|
|
||||||
|
@ViewById(R.id.login)
|
||||||
|
View mLogin;
|
||||||
|
|
||||||
@AfterViews
|
@AfterViews
|
||||||
void setUpViews() {
|
void setUpViews() {
|
||||||
setToolbarAsBack(getString(R.string.text_login));
|
setToolbarAsBack(getString(R.string.text_login));
|
||||||
|
ThemeColorManager.addViewBackground(mLogin);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Click(R.id.login)
|
@Click(R.id.login)
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package com.stardust.scriptdroid.ui.user;
|
|||||||
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.util.Patterns;
|
import android.util.Patterns;
|
||||||
|
import android.view.View;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
@@ -9,6 +10,7 @@ import com.afollestad.materialdialogs.MaterialDialog;
|
|||||||
import com.stardust.scriptdroid.R;
|
import com.stardust.scriptdroid.R;
|
||||||
import com.stardust.scriptdroid.network.UserService;
|
import com.stardust.scriptdroid.network.UserService;
|
||||||
import com.stardust.scriptdroid.ui.BaseActivity;
|
import com.stardust.scriptdroid.ui.BaseActivity;
|
||||||
|
import com.stardust.theme.ThemeColorManager;
|
||||||
|
|
||||||
import org.androidannotations.annotations.AfterViews;
|
import org.androidannotations.annotations.AfterViews;
|
||||||
import org.androidannotations.annotations.Click;
|
import org.androidannotations.annotations.Click;
|
||||||
@@ -33,9 +35,14 @@ public class RegisterActivity extends BaseActivity {
|
|||||||
@ViewById(R.id.password)
|
@ViewById(R.id.password)
|
||||||
TextView mPassword;
|
TextView mPassword;
|
||||||
|
|
||||||
|
@ViewById(R.id.register)
|
||||||
|
View mRegister;
|
||||||
|
|
||||||
|
|
||||||
@AfterViews
|
@AfterViews
|
||||||
void setUpViews() {
|
void setUpViews() {
|
||||||
setToolbarAsBack(getString(R.string.text_register));
|
setToolbarAsBack(getString(R.string.text_register));
|
||||||
|
ThemeColorManager.addViewBackground(mRegister);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Click(R.id.register)
|
@Click(R.id.register)
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
</android.support.design.widget.AppBarLayout>
|
</android.support.design.widget.AppBarLayout>
|
||||||
|
|
||||||
|
|
||||||
<FrameLayout
|
<FrameLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:theme="@style/AppTheme.AppBarOverlay">
|
android:theme="@style/AppTheme.AppBarOverlay">
|
||||||
|
|
||||||
<android.support.v7.widget.Toolbar
|
<com.stardust.theme.widget.ThemeColorToolbar
|
||||||
android:id="@+id/toolbar"
|
android:id="@+id/toolbar"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="?attr/actionBarSize"
|
android:layout_height="?attr/actionBarSize"
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
package com.stardust.autojs.core.accessibility;
|
package com.stardust.autojs.core.accessibility;
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
import android.view.accessibility.AccessibilityNodeInfo;
|
import android.view.accessibility.AccessibilityNodeInfo;
|
||||||
|
|
||||||
import com.stardust.view.accessibility.AccessibilityInfoProvider;
|
import com.stardust.view.accessibility.AccessibilityInfoProvider;
|
||||||
|
import com.stardust.view.accessibility.AccessibilityNotificationObserver;
|
||||||
import com.stardust.view.accessibility.AccessibilityService;
|
import com.stardust.view.accessibility.AccessibilityService;
|
||||||
import com.stardust.view.accessibility.NotificationListener;
|
import com.stardust.view.accessibility.NotificationListener;
|
||||||
|
|
||||||
@@ -48,5 +48,5 @@ public abstract class AccessibilityBridge {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
public abstract NotificationListener.Observer getNotificationObserver();
|
public abstract AccessibilityNotificationObserver getNotificationObserver();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,7 +35,9 @@ public class RunnableScriptExecution extends ScriptExecution.AbstractScriptExecu
|
|||||||
private Object execute(ScriptEngine engine) {
|
private Object execute(ScriptEngine engine) {
|
||||||
try {
|
try {
|
||||||
prepare(engine);
|
prepare(engine);
|
||||||
return doExecution(engine);
|
Object r = doExecution(engine);
|
||||||
|
getListener().onSuccess(this, r);
|
||||||
|
return r;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
getListener().onException(this, e);
|
getListener().onException(this, e);
|
||||||
@@ -67,7 +69,6 @@ public class RunnableScriptExecution extends ScriptExecution.AbstractScriptExecu
|
|||||||
result = execute(engine, source);
|
result = execute(engine, source);
|
||||||
sleep(interval);
|
sleep(interval);
|
||||||
}
|
}
|
||||||
getListener().onSuccess(this, result);
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import com.stardust.autojs.runtime.ScriptBridges;
|
|||||||
import com.stardust.autojs.runtime.exception.ScriptException;
|
import com.stardust.autojs.runtime.exception.ScriptException;
|
||||||
import com.stardust.autojs.core.inputevent.InputEventObserver;
|
import com.stardust.autojs.core.inputevent.InputEventObserver;
|
||||||
import com.stardust.autojs.core.inputevent.TouchObserver;
|
import com.stardust.autojs.core.inputevent.TouchObserver;
|
||||||
|
import com.stardust.view.accessibility.AccessibilityNotificationObserver;
|
||||||
import com.stardust.view.accessibility.AccessibilityService;
|
import com.stardust.view.accessibility.AccessibilityService;
|
||||||
import com.stardust.view.accessibility.NotificationListener;
|
import com.stardust.view.accessibility.NotificationListener;
|
||||||
import com.stardust.view.accessibility.OnKeyListener;
|
import com.stardust.view.accessibility.OnKeyListener;
|
||||||
@@ -25,7 +26,7 @@ import com.stardust.view.accessibility.OnKeyListener;
|
|||||||
* Created by Stardust on 2017/7/18.
|
* Created by Stardust on 2017/7/18.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class Events extends EventEmitter implements OnKeyListener, TouchObserver.OnTouchEventListener, NotificationListener {
|
public class Events extends EventEmitter implements OnKeyListener, TouchObserver.OnTouchEventListener, NotificationListener, AccessibilityNotificationObserver.ToastListener {
|
||||||
|
|
||||||
private static final String PREFIX_KEY_DOWN = "__key_down__#";
|
private static final String PREFIX_KEY_DOWN = "__key_down__#";
|
||||||
private static final String PREFIX_KEY_UP = "__key_up__#";
|
private static final String PREFIX_KEY_UP = "__key_up__#";
|
||||||
@@ -135,6 +136,7 @@ public class Events extends EventEmitter implements OnKeyListener, TouchObserver
|
|||||||
public void observeNotification() {
|
public void observeNotification() {
|
||||||
if (mListeningNotification)
|
if (mListeningNotification)
|
||||||
return;
|
return;
|
||||||
|
mAccessibilityBridge.ensureServiceEnabled();
|
||||||
mListeningNotification = true;
|
mListeningNotification = true;
|
||||||
ensureHandler();
|
ensureHandler();
|
||||||
mLoopers.waitWhenIdle(true);
|
mLoopers.waitWhenIdle(true);
|
||||||
@@ -142,10 +144,9 @@ public class Events extends EventEmitter implements OnKeyListener, TouchObserver
|
|||||||
&& NotificationListenerService.getInstance() != null) {
|
&& NotificationListenerService.getInstance() != null) {
|
||||||
NotificationListenerService.getInstance().addListener(this);
|
NotificationListenerService.getInstance().addListener(this);
|
||||||
} else {
|
} else {
|
||||||
mAccessibilityBridge.ensureServiceEnabled();
|
mAccessibilityBridge.getNotificationObserver().addNotificationListener(this);
|
||||||
mAccessibilityBridge.getNotificationObserver()
|
|
||||||
.addListener(this);
|
|
||||||
}
|
}
|
||||||
|
mAccessibilityBridge.getNotificationObserver().addToastListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Events onNotification(Object listener) {
|
public Events onNotification(Object listener) {
|
||||||
@@ -171,7 +172,8 @@ public class Events extends EventEmitter implements OnKeyListener, TouchObserver
|
|||||||
mTouchObserver.stop();
|
mTouchObserver.stop();
|
||||||
}
|
}
|
||||||
if (mListeningNotification) {
|
if (mListeningNotification) {
|
||||||
mAccessibilityBridge.getNotificationObserver().removeListener(this);
|
mAccessibilityBridge.getNotificationObserver().removeNotificationListener(this);
|
||||||
|
mAccessibilityBridge.getNotificationObserver().removeToastListener(this);
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2
|
||||||
&& NotificationListenerService.getInstance() != null) {
|
&& NotificationListenerService.getInstance() != null) {
|
||||||
NotificationListenerService.getInstance().removeListener(this);
|
NotificationListenerService.getInstance().removeListener(this);
|
||||||
@@ -221,4 +223,14 @@ public class Events extends EventEmitter implements OnKeyListener, TouchObserver
|
|||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onToast(final AccessibilityNotificationObserver.Toast toast) {
|
||||||
|
mHandler.post(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
emit("toast", toast);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,15 +15,6 @@ public class ProcessUtils {
|
|||||||
|
|
||||||
private static final String LOG_TAG = "ProcessUtils";
|
private static final String LOG_TAG = "ProcessUtils";
|
||||||
|
|
||||||
// FIXME: 2017/8/3
|
|
||||||
public static void killProcessTree(Process process) {
|
|
||||||
int pid = getProcessPid(process);
|
|
||||||
if (pid >= 0)
|
|
||||||
kill(pid);
|
|
||||||
process.destroy();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int getProcessPid(Process process) {
|
public static int getProcessPid(Process process) {
|
||||||
try {
|
try {
|
||||||
Field pid = process.getClass().getDeclaredField("pid");
|
Field pid = process.getClass().getDeclaredField("pid");
|
||||||
@@ -35,9 +26,4 @@ public class ProcessUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void kill(int pid) {
|
|
||||||
String cmd = "kill -TERM -- -" + pid;
|
|
||||||
Log.d(LOG_TAG, cmd);
|
|
||||||
ProcessShell.exec(cmd, true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,6 +53,18 @@ public class Notification extends android.app.Notification {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||||
|
return "Notification{" +
|
||||||
|
"packageName='" + mPackageName + '\'' +
|
||||||
|
"title = " + getTitle() + '\'' +
|
||||||
|
"text='" + getText() + '\'' +
|
||||||
|
"} ";
|
||||||
|
}
|
||||||
|
return super.toString();
|
||||||
|
}
|
||||||
|
|
||||||
public static void clone(android.app.Notification from, android.app.Notification to) {
|
public static void clone(android.app.Notification from, android.app.Notification to) {
|
||||||
to.when = from.when;
|
to.when = from.when;
|
||||||
to.icon = from.icon;
|
to.icon = from.icon;
|
||||||
|
|||||||
@@ -0,0 +1,146 @@
|
|||||||
|
package com.stardust.view.accessibility;
|
||||||
|
|
||||||
|
import android.accessibilityservice.*;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.accessibility.AccessibilityEvent;
|
||||||
|
|
||||||
|
import com.stardust.notification.Notification;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Stardust on 2017/11/3.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class AccessibilityNotificationObserver implements NotificationListener, AccessibilityDelegate {
|
||||||
|
|
||||||
|
public class Toast {
|
||||||
|
public final List<String> texts;
|
||||||
|
public final String packageName;
|
||||||
|
|
||||||
|
public Toast(String packageName, List<CharSequence> texts) {
|
||||||
|
this.texts = new ArrayList<>(texts.size());
|
||||||
|
for (CharSequence t : texts) {
|
||||||
|
if (t != null) {
|
||||||
|
this.texts.add(t.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.packageName = packageName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getText() {
|
||||||
|
if (texts.isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
CharSequence text = texts.get(0);
|
||||||
|
if (text == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return text.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getTexts() {
|
||||||
|
return texts;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPackageName() {
|
||||||
|
return packageName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Toast{" +
|
||||||
|
"texts=" + texts +
|
||||||
|
", packageName='" + packageName + '\'' +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface ToastListener {
|
||||||
|
void onToast(Toast toast);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final Set<Integer> EVENT_TYPES = Collections.singleton(AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED);
|
||||||
|
|
||||||
|
private static final String TAG = "NotificationObserver";
|
||||||
|
private static final String[] EMPTY = new String[0];
|
||||||
|
|
||||||
|
private Context mContext;
|
||||||
|
private CopyOnWriteArrayList<NotificationListener> mNotificationListeners = new CopyOnWriteArrayList<>();
|
||||||
|
private CopyOnWriteArrayList<ToastListener> mToastListeners = new CopyOnWriteArrayList<>();
|
||||||
|
|
||||||
|
public AccessibilityNotificationObserver(Context context) {
|
||||||
|
mContext = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void addNotificationListener(NotificationListener listener) {
|
||||||
|
mNotificationListeners.add(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean removeNotificationListener(NotificationListener listener) {
|
||||||
|
return mNotificationListeners.remove(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void addToastListener(ToastListener listener) {
|
||||||
|
mToastListeners.add(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean removeToastListener(ToastListener listener) {
|
||||||
|
return mToastListeners.remove(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onAccessibilityEvent(android.accessibilityservice.AccessibilityService service, AccessibilityEvent event) {
|
||||||
|
if (event.getParcelableData() instanceof Notification) {
|
||||||
|
android.app.Notification notification = (android.app.Notification) event.getParcelableData();
|
||||||
|
Log.d(TAG, "onNotification: " + notification + "; " + event);
|
||||||
|
onNotification(Notification.create(notification, event.getPackageName().toString()));
|
||||||
|
} else {
|
||||||
|
List<CharSequence> list = event.getText();
|
||||||
|
Log.d(TAG, "onNotification: " + list + "; " + event);
|
||||||
|
if (event.getPackageName().equals(mContext.getPackageName())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (list != null) {
|
||||||
|
onToast(event, new Toast(event.getPackageName().toString(), list));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onToast(AccessibilityEvent event, Toast toast) {
|
||||||
|
for (ToastListener listener : mToastListeners) {
|
||||||
|
try {
|
||||||
|
listener.onToast(toast);
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e(TAG, "Error onNotification: " + toast + " Listener: " + listener, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public Set<Integer> getEventTypes() {
|
||||||
|
return EVENT_TYPES;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNotification(Notification notification) {
|
||||||
|
for (NotificationListener listener : mNotificationListeners) {
|
||||||
|
try {
|
||||||
|
listener.onNotification(notification);
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e(TAG, "Error onNotification: " + notification + " Listener: " + listener, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -22,112 +22,7 @@ import java.util.concurrent.CopyOnWriteArrayList;
|
|||||||
public interface NotificationListener {
|
public interface NotificationListener {
|
||||||
|
|
||||||
|
|
||||||
class NotificationInfo {
|
|
||||||
|
|
||||||
private String mPackageName;
|
|
||||||
private String mText;
|
|
||||||
private List<String> mTexts;
|
|
||||||
|
|
||||||
public NotificationInfo(String packageName, List<String> texts) {
|
|
||||||
mPackageName = packageName;
|
|
||||||
mTexts = texts;
|
|
||||||
if (mTexts.size() > 0) {
|
|
||||||
mText = mTexts.get(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public NotificationInfo(CharSequence packageName, List<CharSequence> list) {
|
|
||||||
mPackageName = packageName == null ? "" : packageName.toString();
|
|
||||||
mTexts = new ArrayList<>(list.size());
|
|
||||||
for (CharSequence text : list) {
|
|
||||||
if (text != null) {
|
|
||||||
mTexts.add(text.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (mTexts.size() > 0) {
|
|
||||||
mText = mTexts.get(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static NotificationInfo fromEvent(AccessibilityEvent event) {
|
|
||||||
return new NotificationInfo(event.getPackageName(), event.getText());
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getPackageName() {
|
|
||||||
return mPackageName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getText() {
|
|
||||||
return mText;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<String> getTexts() {
|
|
||||||
return mTexts;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "NotificationInfo{" +
|
|
||||||
"packageName='" + mPackageName + '\'' +
|
|
||||||
", text='" + mText + '\'' +
|
|
||||||
", texts=" + mTexts +
|
|
||||||
'}';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void onNotification(Notification notification);
|
void onNotification(Notification notification);
|
||||||
|
|
||||||
|
|
||||||
class Observer implements NotificationListener, AccessibilityDelegate {
|
|
||||||
|
|
||||||
private static final Set<Integer> EVENT_TYPES = Collections.singleton(AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED);
|
|
||||||
|
|
||||||
private static final String TAG = "NotificationObserver";
|
|
||||||
private static final String[] EMPTY = new String[0];
|
|
||||||
|
|
||||||
private Context mContext;
|
|
||||||
private CopyOnWriteArrayList<NotificationListener> mNotificationListeners = new CopyOnWriteArrayList<>();
|
|
||||||
|
|
||||||
public Observer(Context context) {
|
|
||||||
mContext = context;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void addListener(NotificationListener listener) {
|
|
||||||
mNotificationListeners.add(listener);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean removeListener(NotificationListener listener) {
|
|
||||||
return mNotificationListeners.remove(listener);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onAccessibilityEvent(AccessibilityService service, AccessibilityEvent event) {
|
|
||||||
if (event.getParcelableData() instanceof Notification) {
|
|
||||||
android.app.Notification notification = (android.app.Notification) event.getParcelableData();
|
|
||||||
Log.d(TAG, "onNotification: " + notification + "; " + event);
|
|
||||||
onNotification(Notification.create(notification, event.getPackageName().toString()));
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
|
||||||
public Set<Integer> getEventTypes() {
|
|
||||||
return EVENT_TYPES;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onNotification(Notification notification) {
|
|
||||||
for (NotificationListener listener : mNotificationListeners) {
|
|
||||||
try {
|
|
||||||
listener.onNotification(notification);
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log.e(TAG, "Error onNotification: " + notification + " Listener: " + listener, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,7 +45,6 @@ public interface OnActivityResultDelegate {
|
|||||||
|
|
||||||
public void removeDelegate(OnActivityResultDelegate delegate) {
|
public void removeDelegate(OnActivityResultDelegate delegate) {
|
||||||
if (mDelegates.remove(delegate)) {
|
if (mDelegates.remove(delegate)) {
|
||||||
// TODO: 2017/3/16 优化
|
|
||||||
mSpecialDelegate.removeAt(mSpecialDelegate.indexOfValue(delegate));
|
mSpecialDelegate.removeAt(mSpecialDelegate.indexOfValue(delegate));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ public class AutoJs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private final AccessibilityActionRecorder mAccessibilityActionRecorder = new AccessibilityActionRecorder();
|
private final AccessibilityActionRecorder mAccessibilityActionRecorder = new AccessibilityActionRecorder();
|
||||||
private final NotificationListener.Observer mNotificationObserver;
|
private final NotificationListener.AccessibilityNotificationObserver mNotificationObserver;
|
||||||
private ScriptEngineManager mScriptEngineManager;
|
private ScriptEngineManager mScriptEngineManager;
|
||||||
private final Context mContext;
|
private final Context mContext;
|
||||||
private final UiHandler mUiHandler;
|
private final UiHandler mUiHandler;
|
||||||
@@ -74,7 +74,7 @@ public class AutoJs {
|
|||||||
mUiHandler = new UiHandler(context);
|
mUiHandler = new UiHandler(context);
|
||||||
mAppUtils = new AppUtils(context);
|
mAppUtils = new AppUtils(context);
|
||||||
mGlobalConsole = new GlobalStardustConsole(mUiHandler);
|
mGlobalConsole = new GlobalStardustConsole(mUiHandler);
|
||||||
mNotificationObserver = new NotificationListener.Observer(context);
|
mNotificationObserver = new NotificationListener.AccessibilityNotificationObserver(context);
|
||||||
mAccessibilityInfoProvider = new AccessibilityInfoProvider(context.getPackageManager());
|
mAccessibilityInfoProvider = new AccessibilityInfoProvider(context.getPackageManager());
|
||||||
mScriptEngineService = buildScriptEngineService();
|
mScriptEngineService = buildScriptEngineService();
|
||||||
addAccessibilityServiceDelegates();
|
addAccessibilityServiceDelegates();
|
||||||
@@ -198,7 +198,7 @@ public class AutoJs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NotificationListener.Observer getNotificationObserver() {
|
public NotificationListener.AccessibilityNotificationObserver getNotificationObserver() {
|
||||||
return mNotificationObserver;
|
return mNotificationObserver;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user