blob: 53db1258f620ff79087194a885733907c772d64c [file] [log] [blame]
package foo.bar.testback;
import android.accessibilityservice.AccessibilityService;
import android.accessibilityservice.AccessibilityServiceInfo;
import android.content.Context;
import android.util.ArraySet;
import android.util.Log;
import android.view.WindowManager;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.accessibility.AccessibilityWindowInfo;
import android.widget.Button;
import java.util.List;
import java.util.Set;
public class TestBackService extends AccessibilityService {
private static final String LOG_TAG = TestBackService.class.getSimpleName();
private Button mButton;
@Override
public void onCreate() {
super.onCreate();
mButton = new Button(this);
mButton.setText("Button 1");
}
@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
// if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
// Log.i(LOG_TAG, event.getText().toString());
// //dumpWindows();
// }
if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_HOVER_ENTER) {
// Log.i(LOG_TAG, "Click event.isChecked()=" + event.isChecked()
// + ((event.getSource() != null) ? " node.isChecked()="
// + event.getSource().isChecked() : " node=null"));
AccessibilityNodeInfo source = event.getSource();
dumpWindow(source);
// AccessibilityNodeInfo node = event.getSource();
// if (node != null) {
// node.refresh();
// Log.i(LOG_TAG, "Clicked: " + node.getClassName() + " clicked:" + node.isChecked());
// }
}
}
@Override
protected boolean onGesture(int gestureId) {
switch (gestureId) {
case AccessibilityService.GESTURE_SWIPE_DOWN: {
showAccessibilityOverlay();
} break;
case AccessibilityService.GESTURE_SWIPE_UP: {
hideAccessibilityOverlay();
} break;
}
return super.onGesture(gestureId);
}
private void showAccessibilityOverlay() {
WindowManager.LayoutParams params = new WindowManager.LayoutParams();
params.flags = WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
| WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR
| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
params.type = WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY;
WindowManager windowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
windowManager.addView(mButton, params);
}
private void hideAccessibilityOverlay() {
WindowManager windowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
windowManager.removeView(mButton);
}
private void dumpWindows() {
List<AccessibilityWindowInfo> windows = getWindows();
final int windowCount = windows.size();
for (int i = 0; i < windowCount; i++) {
AccessibilityWindowInfo window = windows.get(i);
Log.i(LOG_TAG, "=============================");
Log.i(LOG_TAG, window.toString());
}
}
private void dumpWindow(AccessibilityNodeInfo source) {
AccessibilityNodeInfo root = source;
while (true) {
AccessibilityNodeInfo parent = root.getParent();
if (parent == null) {
break;
} else if (parent.equals(root)) {
Log.i(LOG_TAG, "Node is own parent:" + root);
}
root = parent;
}
dumpTree(root, new ArraySet<AccessibilityNodeInfo>());
}
private void dumpTree(AccessibilityNodeInfo root, Set<AccessibilityNodeInfo> visited) {
if (root == null) {
return;
}
if (!visited.add(root)) {
Log.i(LOG_TAG, "Cycle detected to node:" + root);
}
final int childCount = root.getChildCount();
for (int i = 0; i < childCount; i++) {
AccessibilityNodeInfo child = root.getChild(i);
if (child != null) {
AccessibilityNodeInfo parent = child.getParent();
if (parent == null) {
Log.e(LOG_TAG, "Child of a node has no parent");
} else if (!parent.equals(root)) {
Log.e(LOG_TAG, "Child of a node has wrong parent");
}
Log.i(LOG_TAG, child.toString());
}
}
for (int i = 0; i < childCount; i++) {
AccessibilityNodeInfo child = root.getChild(i);
dumpTree(child, visited);
}
}
@Override
public void onInterrupt() {
/* ignore */
}
@Override
public void onServiceConnected() {
AccessibilityServiceInfo info = getServiceInfo();
info.flags |= AccessibilityServiceInfo.FLAG_REPORT_VIEW_IDS;
info.flags |= AccessibilityServiceInfo.FLAG_REQUEST_TOUCH_EXPLORATION_MODE;
info.flags |= AccessibilityServiceInfo.FLAG_RETRIEVE_INTERACTIVE_WINDOWS;
setServiceInfo(info);
}
}