summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorSvetoslav <svetoslavganov@google.com>2014-10-23 23:17:20 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2014-10-23 23:17:21 +0000
commitbd6fabe2ae535cf5d31fc7a1952e43ad6e653e2e (patch)
tree086532257ec25a3c7e3329fb2d9d2146bb15f5ca /core
parent9920a0dcf15ba2036cdcc5d6548efa6b4a8bc944 (diff)
parent3a5c721072c60c7ed9c8a95d0a65d0e3cb4eb9bb (diff)
downloadframeworks_base-bd6fabe2ae535cf5d31fc7a1952e43ad6e653e2e.zip
frameworks_base-bd6fabe2ae535cf5d31fc7a1952e43ad6e653e2e.tar.gz
frameworks_base-bd6fabe2ae535cf5d31fc7a1952e43ad6e653e2e.tar.bz2
Merge "APIs for an accessibility service to put interaction tracking overlays." into lmp-mr1-dev
Diffstat (limited to 'core')
-rw-r--r--core/java/android/accessibilityservice/AccessibilityService.java96
-rw-r--r--core/java/android/accessibilityservice/IAccessibilityServiceClient.aidl2
-rw-r--r--core/java/android/app/UiAutomation.java3
-rw-r--r--core/java/android/view/WindowManager.java13
-rw-r--r--core/java/android/view/WindowManagerInternal.java16
-rw-r--r--core/java/android/view/accessibility/AccessibilityWindowInfo.java35
6 files changed, 144 insertions, 21 deletions
diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java
index 13ceb4a..1e1b33f 100644
--- a/core/java/android/accessibilityservice/AccessibilityService.java
+++ b/core/java/android/accessibilityservice/AccessibilityService.java
@@ -24,13 +24,18 @@ import android.os.Looper;
import android.os.Message;
import android.os.RemoteException;
import android.util.Log;
+import android.view.Display;
import android.view.KeyEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.WindowManager;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityInteractionClient;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.accessibility.AccessibilityWindowInfo;
import com.android.internal.os.HandlerCaller;
+import com.android.internal.os.SomeArgs;
import java.util.List;
@@ -366,7 +371,7 @@ public abstract class AccessibilityService extends Service {
public void onAccessibilityEvent(AccessibilityEvent event);
public void onInterrupt();
public void onServiceConnected();
- public void onSetConnectionId(int connectionId);
+ public void init(int connectionId, IBinder windowToken);
public boolean onGesture(int gestureId);
public boolean onKeyEvent(KeyEvent event);
}
@@ -375,6 +380,10 @@ public abstract class AccessibilityService extends Service {
private AccessibilityServiceInfo mInfo;
+ private IBinder mWindowToken;
+
+ private WindowManager mWindowManager;
+
/**
* Callback for {@link android.view.accessibility.AccessibilityEvent}s.
*
@@ -611,6 +620,18 @@ public abstract class AccessibilityService extends Service {
}
}
+ @Override
+ public Object getSystemService(String name) {
+ if (Context.WINDOW_SERVICE.equals(name)) {
+ if (mWindowManager == null) {
+ WindowManager wrapped = (WindowManager) super.getSystemService(name);
+ mWindowManager = new LocalWindowManager(wrapped);
+ }
+ return mWindowManager;
+ }
+ return super.getSystemService(name);
+ }
+
/**
* Implement to return the implementation of the internal accessibility
* service interface.
@@ -634,8 +655,9 @@ public abstract class AccessibilityService extends Service {
}
@Override
- public void onSetConnectionId( int connectionId) {
+ public void init(int connectionId, IBinder windowToken) {
mConnectionId = connectionId;
+ mWindowToken = windowToken;
}
@Override
@@ -658,7 +680,7 @@ public abstract class AccessibilityService extends Service {
*/
public static class IAccessibilityServiceClientWrapper extends IAccessibilityServiceClient.Stub
implements HandlerCaller.Callback {
- private static final int DO_SET_SET_CONNECTION = 1;
+ private static final int DO_INIT = 1;
private static final int DO_ON_INTERRUPT = 2;
private static final int DO_ON_ACCESSIBILITY_EVENT = 3;
private static final int DO_ON_GESTURE = 4;
@@ -677,9 +699,10 @@ public abstract class AccessibilityService extends Service {
mCaller = new HandlerCaller(context, looper, this, true /*asyncHandler*/);
}
- public void setConnection(IAccessibilityServiceConnection connection, int connectionId) {
- Message message = mCaller.obtainMessageIO(DO_SET_SET_CONNECTION, connectionId,
- connection);
+ public void init(IAccessibilityServiceConnection connection, int connectionId,
+ IBinder windowToken) {
+ Message message = mCaller.obtainMessageIOO(DO_INIT, connectionId,
+ connection, windowToken);
mCaller.sendMessage(message);
}
@@ -730,20 +753,24 @@ public abstract class AccessibilityService extends Service {
mCallback.onInterrupt();
} return;
- case DO_SET_SET_CONNECTION: {
+ case DO_INIT: {
mConnectionId = message.arg1;
+ SomeArgs args = (SomeArgs) message.obj;
IAccessibilityServiceConnection connection =
- (IAccessibilityServiceConnection) message.obj;
+ (IAccessibilityServiceConnection) args.arg1;
+ IBinder windowToken = (IBinder) args.arg2;
+ args.recycle();
if (connection != null) {
AccessibilityInteractionClient.getInstance().addConnection(mConnectionId,
connection);
- mCallback.onSetConnectionId(mConnectionId);
+ mCallback.init(mConnectionId, windowToken);
mCallback.onServiceConnected();
} else {
AccessibilityInteractionClient.getInstance().removeConnection(
mConnectionId);
+ mConnectionId = AccessibilityInteractionClient.NO_ID;
AccessibilityInteractionClient.getInstance().clearCache();
- mCallback.onSetConnectionId(AccessibilityInteractionClient.NO_ID);
+ mCallback.init(AccessibilityInteractionClient.NO_ID, null);
}
} return;
@@ -785,4 +812,53 @@ public abstract class AccessibilityService extends Service {
}
}
}
+
+ private class LocalWindowManager implements WindowManager {
+ private final WindowManager mImpl;
+
+ private LocalWindowManager(WindowManager impl) {
+ mImpl = impl;
+ }
+
+ @Override
+ public Display getDefaultDisplay() {
+ return mImpl.getDefaultDisplay();
+ }
+
+ @Override
+ public void addView(View view, ViewGroup.LayoutParams params) {
+ if (!(params instanceof WindowManager.LayoutParams)) {
+ throw new IllegalArgumentException("Params must be WindowManager.LayoutParams");
+ }
+ WindowManager.LayoutParams windowParams = (WindowManager.LayoutParams) params;
+ if (windowParams.type == LayoutParams.TYPE_ACCESSIBILITY_OVERLAY
+ && windowParams.token == null) {
+ windowParams.token = mWindowToken;
+ }
+ mImpl.addView(view, params);
+ }
+
+ @Override
+ public void updateViewLayout(View view, ViewGroup.LayoutParams params) {
+ if (!(params instanceof WindowManager.LayoutParams)) {
+ throw new IllegalArgumentException("Params must be WindowManager.LayoutParams");
+ }
+ WindowManager.LayoutParams windowParams = (WindowManager.LayoutParams) params;
+ if (windowParams.type == LayoutParams.TYPE_ACCESSIBILITY_OVERLAY
+ && windowParams.token == null) {
+ windowParams.token = mWindowToken;
+ }
+ mImpl.updateViewLayout(view, params);
+ }
+
+ @Override
+ public void removeViewImmediate(View view) {
+ mImpl.removeViewImmediate(view);
+ }
+
+ @Override
+ public void removeView(View view) {
+ mImpl.removeView(view);
+ }
+ }
}
diff --git a/core/java/android/accessibilityservice/IAccessibilityServiceClient.aidl b/core/java/android/accessibilityservice/IAccessibilityServiceClient.aidl
index 6ce0219..8b503dd 100644
--- a/core/java/android/accessibilityservice/IAccessibilityServiceClient.aidl
+++ b/core/java/android/accessibilityservice/IAccessibilityServiceClient.aidl
@@ -28,7 +28,7 @@ import android.view.KeyEvent;
*/
oneway interface IAccessibilityServiceClient {
- void setConnection(in IAccessibilityServiceConnection connection, int connectionId);
+ void init(in IAccessibilityServiceConnection connection, int connectionId, IBinder windowToken);
void onAccessibilityEvent(in AccessibilityEvent event);
diff --git a/core/java/android/app/UiAutomation.java b/core/java/android/app/UiAutomation.java
index 4aec9e0..b0dd70f 100644
--- a/core/java/android/app/UiAutomation.java
+++ b/core/java/android/app/UiAutomation.java
@@ -25,6 +25,7 @@ import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Point;
import android.hardware.display.DisplayManagerGlobal;
+import android.os.IBinder;
import android.os.Looper;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
@@ -919,7 +920,7 @@ public final class UiAutomation {
public IAccessibilityServiceClientImpl(Looper looper) {
super(null, looper, new Callbacks() {
@Override
- public void onSetConnectionId(int connectionId) {
+ public void init(int connectionId, IBinder windowToken) {
synchronized (mLock) {
mConnectionId = connectionId;
mLock.notifyAll();
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 3f84c9b..5b48c0d 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -542,6 +542,19 @@ public interface WindowManager extends ViewManager {
public static final int TYPE_VOICE_INTERACTION = FIRST_SYSTEM_WINDOW+31;
/**
+ * Window type: Windows that are overlaid <em>only</em> by an {@link
+ * android.accessibilityservice.AccessibilityService} for interception of
+ * user interactions without changing the windows an accessibility service
+ * can introspect. In particular, an accessibility service can introspect
+ * only windows that a sighted user can interact with which is they can touch
+ * these windows or can type into these windows. For example, if there
+ * is a full screen accessibility overlay that is touchable, the windows
+ * below it will be introspectable by an accessibility service regardless
+ * they are covered by a touchable window.
+ */
+ public static final int TYPE_ACCESSIBILITY_OVERLAY = FIRST_SYSTEM_WINDOW+32;
+
+ /**
* End of types of system windows.
*/
public static final int LAST_SYSTEM_WINDOW = 2999;
diff --git a/core/java/android/view/WindowManagerInternal.java b/core/java/android/view/WindowManagerInternal.java
index 38e3723..f557b97 100644
--- a/core/java/android/view/WindowManagerInternal.java
+++ b/core/java/android/view/WindowManagerInternal.java
@@ -173,4 +173,20 @@ public abstract class WindowManagerInternal {
* redrawn.
*/
public abstract void waitForAllWindowsDrawn(Runnable callback, long timeout);
+
+ /**
+ * Adds a window token for a given window type.
+ *
+ * @param token The token to add.
+ * @param type The window type.
+ */
+ public abstract void addWindowToken(android.os.IBinder token, int type);
+
+ /**
+ * Removes a window token.
+ *
+ * @param token The toke to remove.
+ * @param removeWindows Whether to also remove the windows associated with the token.
+ */
+ public abstract void removeWindowToken(android.os.IBinder token, boolean removeWindows);
}
diff --git a/core/java/android/view/accessibility/AccessibilityWindowInfo.java b/core/java/android/view/accessibility/AccessibilityWindowInfo.java
index ad55f5f..e1942be 100644
--- a/core/java/android/view/accessibility/AccessibilityWindowInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityWindowInfo.java
@@ -51,11 +51,24 @@ public final class AccessibilityWindowInfo implements Parcelable {
*/
public static final int TYPE_SYSTEM = 3;
+ /**
+ * Window type: Windows that are overlaid <em>only</em> by an {@link
+ * android.accessibilityservice.AccessibilityService} for interception of
+ * user interactions without changing the windows an accessibility service
+ * can introspect. In particular, an accessibility service can introspect
+ * only windows that a sighted user can interact with which they can touch
+ * these windows or can type into these windows. For example, if there
+ * is a full screen accessibility overlay that is touchable, the windows
+ * below it will be introspectable by an accessibility service regardless
+ * they are covered by a touchable window.
+ */
+ public static final int TYPE_ACCESSIBILITY_OVERLAY = 4;
+
private static final int UNDEFINED = -1;
private static final int BOOLEAN_PROPERTY_ACTIVE = 1 << 0;
private static final int BOOLEAN_PROPERTY_FOCUSED = 1 << 1;
- private static final int BOOLEAN_PROPERTY_ACCESSIBLITY_FOCUSED = 1 << 2;
+ private static final int BOOLEAN_PROPERTY_ACCESSIBILITY_FOCUSED = 1 << 2;
// Housekeeping.
private static final int MAX_POOL_SIZE = 10;
@@ -85,6 +98,7 @@ public final class AccessibilityWindowInfo implements Parcelable {
* @see #TYPE_APPLICATION
* @see #TYPE_INPUT_METHOD
* @see #TYPE_SYSTEM
+ * @see #TYPE_ACCESSIBILITY_OVERLAY
*/
public int getType() {
return mType;
@@ -93,7 +107,7 @@ public final class AccessibilityWindowInfo implements Parcelable {
/**
* Sets the type of the window.
*
- * @param The type
+ * @param type The type
*
* @hide
*/
@@ -115,7 +129,7 @@ public final class AccessibilityWindowInfo implements Parcelable {
* Sets the layer which determines the Z-order of the window. Windows
* with greater layer appear on top of windows with lesser layer.
*
- * @param The window layer.
+ * @param layer The window layer.
*
* @hide
*/
@@ -174,7 +188,7 @@ public final class AccessibilityWindowInfo implements Parcelable {
/**
* Sets the unique window id.
*
- * @param windowId The window id.
+ * @param id The window id.
*
* @hide
*/
@@ -230,7 +244,7 @@ public final class AccessibilityWindowInfo implements Parcelable {
* the user is currently touching or the window has input focus
* and the user is not touching any window.
*
- * @param Whether this is the active window.
+ * @param active Whether this is the active window.
*
* @hide
*/
@@ -250,7 +264,7 @@ public final class AccessibilityWindowInfo implements Parcelable {
/**
* Sets if this window has input focus.
*
- * @param Whether has input focus.
+ * @param focused Whether has input focus.
*
* @hide
*/
@@ -264,18 +278,18 @@ public final class AccessibilityWindowInfo implements Parcelable {
* @return Whether has accessibility focus.
*/
public boolean isAccessibilityFocused() {
- return getBooleanProperty(BOOLEAN_PROPERTY_ACCESSIBLITY_FOCUSED);
+ return getBooleanProperty(BOOLEAN_PROPERTY_ACCESSIBILITY_FOCUSED);
}
/**
* Sets if this window has accessibility focus.
*
- * @param Whether has accessibility focus.
+ * @param focused Whether has accessibility focus.
*
* @hide
*/
public void setAccessibilityFocused(boolean focused) {
- setBooleanProperty(BOOLEAN_PROPERTY_ACCESSIBLITY_FOCUSED, focused);
+ setBooleanProperty(BOOLEAN_PROPERTY_ACCESSIBILITY_FOCUSED, focused);
}
/**
@@ -534,6 +548,9 @@ public final class AccessibilityWindowInfo implements Parcelable {
case TYPE_SYSTEM: {
return "TYPE_SYSTEM";
}
+ case TYPE_ACCESSIBILITY_OVERLAY: {
+ return "TYPE_ACCESSIBILITY_OVERLAY";
+ }
default:
return "<UNKNOWN>";
}