upload android base code part8
13
android/packages/experimental/TestBack/Android.mk
Normal file
|
@ -0,0 +1,13 @@
|
|||
LOCAL_PATH:= $(call my-dir)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
|
||||
LOCAL_SRC_FILES := $(call all-java-files-under, src)
|
||||
|
||||
LOCAL_PACKAGE_NAME := TestBack
|
||||
|
||||
LOCAL_CERTIFICATE := platform
|
||||
|
||||
include $(BUILD_PACKAGE)
|
28
android/packages/experimental/TestBack/AndroidManifest.xml
Normal file
|
@ -0,0 +1,28 @@
|
|||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="foo.bar.testback"
|
||||
android:versionCode="1"
|
||||
android:versionName="1.0" >
|
||||
|
||||
<uses-permission android:name="android.permission.CAN_REQUEST_TOUCH_EXPLORATION_MODE"/>
|
||||
<uses-permission android:name="android.permission.CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY"/>
|
||||
|
||||
<uses-sdk
|
||||
android:minSdkVersion="21" />
|
||||
|
||||
<application
|
||||
android:icon="@drawable/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:allowBackup="false" >
|
||||
<service
|
||||
android:name=".TestBackService"
|
||||
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
|
||||
<intent-filter>
|
||||
<action android:name="android.accessibilityservice.AccessibilityService" />
|
||||
</intent-filter>
|
||||
<meta-data
|
||||
android:name="android.accessibilityservice"
|
||||
android:resource="@xml/accessibilityservice" />
|
||||
</service>
|
||||
</application>
|
||||
|
||||
</manifest>
|
After Width: | Height: | Size: 3 KiB |
After Width: | Height: | Size: 2.9 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 3 KiB |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 3.9 KiB |
|
@ -0,0 +1,6 @@
|
|||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:id="@+id/menu_settings"
|
||||
android:title="@string/menu_settings"
|
||||
android:orderInCategory="100"
|
||||
android:showAsAction="never" />
|
||||
</menu>
|
|
@ -0,0 +1,5 @@
|
|||
<resources>
|
||||
|
||||
<style name="AppTheme" parent="android:Theme.Holo.Light" />
|
||||
|
||||
</resources>
|
|
@ -0,0 +1,5 @@
|
|||
<resources>
|
||||
|
||||
<style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar" />
|
||||
|
||||
</resources>
|
|
@ -0,0 +1,8 @@
|
|||
<resources>
|
||||
|
||||
<string name="app_name">TestBack</string>
|
||||
<string name="hello_world">Hello world!</string>
|
||||
<string name="menu_settings">Settings</string>
|
||||
<string name="title_activity_main">MainActivity</string>
|
||||
|
||||
</resources>
|
|
@ -0,0 +1,5 @@
|
|||
<resources>
|
||||
|
||||
<style name="AppTheme" parent="android:Theme.Light" />
|
||||
|
||||
</resources>
|
|
@ -0,0 +1,6 @@
|
|||
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:accessibilityFeedbackType="feedbackHaptic"
|
||||
android:accessibilityEventTypes="typeAllMask"
|
||||
android:canRetrieveWindowContent="true"
|
||||
android:canRequestTouchExplorationMode="true"
|
||||
/>
|
|
@ -0,0 +1,148 @@
|
|||
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);
|
||||
}
|
||||
}
|