package com.stardust.scriptdroid.service;
import android.accessibilityservice.AccessibilityServiceInfo;
import android.content.Context;
import android.os.Build;
import android.util.Log;
import android.view.KeyEvent;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
import com.nickandjerry.dynamiclayoutinflator.lib.DynamicLayoutInflator;
import com.stardust.scriptdroid.tool.AccessibilityServiceTool;
import com.stardust.view.accessibility.AccessibilityDelegate;
import com.stardust.view.accessibility.AccessibilityService;
import com.stardust.view.accessibility.AccessibilityServiceUtils;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;
/**
* Created by Stardust on 2017/2/14.
*/
public class AccessibilityWatchDogService extends AccessibilityService {
private static final String TAG = "AccessibilityWatchDog";
private static final SortedMap<Integer, AccessibilityDelegate> mDelegates = new TreeMap<>();
private static final Object LOCK = new Object();
private static AccessibilityWatchDogService instance;
private static boolean containsAllEventTypes = false;
private static final Set<Integer> eventTypes = new HashSet<>();
public static void addDelegate(int uniquePriority, AccessibilityDelegate delegate) {
mDelegates.put(uniquePriority, delegate);
Set<Integer> set = delegate.getEventTypes();
if (set == null)
containsAllEventTypes = true;
else
eventTypes.addAll(set);
}
public static boolean isEnable(Context context) {
return AccessibilityServiceUtils.isAccessibilityServiceEnabled(context, AccessibilityWatchDogService.class);
}
public static AccessibilityWatchDogService getInstance() {
return instance;
}
@Override
public void onAccessibilityEvent(final AccessibilityEvent event) {
if (event.getEventType() == AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED) {
}
Log.v(TAG, "onAccessibilityEvent: " + event);
if (!containsAllEventTypes && !eventTypes.contains(event.getEventType()))
return;
for (Map.Entry<Integer, AccessibilityDelegate> entry : mDelegates.entrySet()) {
AccessibilityDelegate delegate = entry.getValue();
Set<Integer> types = delegate.getEventTypes();
if (types != null && !delegate.getEventTypes().contains(event.getEventType()))
continue;
long start = System.currentTimeMillis();
if (delegate.onAccessibilityEvent(AccessibilityWatchDogService.this, event))
break;
Log.v(TAG, "millis: " + (System.currentTimeMillis() - start) + " delegate: " + entry.getValue().getClass().getName());
}
}
@Override
protected boolean onKeyEvent(KeyEvent event) {
Log.v(TAG, "onKeyEvent: " + event);
return super.onKeyEvent(event);
}
@Override
protected boolean onGesture(int gestureId) {
Log.v(TAG, "onGesture: " + gestureId);
return super.onGesture(gestureId);
}
@Override
public void onInterrupt() {
}
@Override
public void onDestroy() {
instance = null;
super.onDestroy();
}
@Override
protected void onServiceConnected() {
Log.v(TAG, "onServiceConnected: " + getServiceInfo().toString());
instance = this;
super.onServiceConnected();
synchronized (LOCK) {
LOCK.notifyAll();
}
// FIXME: 2017/2/12 有时在无障碍中开启服务后这里不会调用服务也不会运行,安卓的BUG???
}
public static void disable() {
if (instance != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
instance.disableSelf();
} else {
AccessibilityServiceTool.goToAccessibilitySetting();
}
}
public static void waitForEnabled(long timeOut) {
synchronized (LOCK) {
try {
LOCK.wait(timeOut);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}