summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--api/current.txt2
-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
-rw-r--r--policy/src/com/android/internal/policy/impl/PhoneWindowManager.java13
-rw-r--r--services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java35
-rw-r--r--services/core/java/com/android/server/wm/AccessibilityController.java14
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java29
-rw-r--r--services/core/java/com/android/server/wm/WindowToken.java12
12 files changed, 234 insertions, 36 deletions
diff --git a/api/current.txt b/api/current.txt
index f14daa7..20cf89c 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -34967,6 +34967,7 @@ package android.view {
field public static final int SOFT_INPUT_STATE_UNSPECIFIED = 0; // 0x0
field public static final int SOFT_INPUT_STATE_VISIBLE = 4; // 0x4
field public static final int TITLE_CHANGED = 64; // 0x40
+ field public static final int TYPE_ACCESSIBILITY_OVERLAY = 2032; // 0x7f0
field public static final int TYPE_APPLICATION = 2; // 0x2
field public static final int TYPE_APPLICATION_ATTACHED_DIALOG = 1003; // 0x3eb
field public static final int TYPE_APPLICATION_MEDIA = 1001; // 0x3e9
@@ -35386,6 +35387,7 @@ package android.view.accessibility {
method public void recycle();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator CREATOR;
+ field public static final int TYPE_ACCESSIBILITY_OVERLAY = 4; // 0x4
field public static final int TYPE_APPLICATION = 1; // 0x1
field public static final int TYPE_INPUT_METHOD = 2; // 0x2
field public static final int TYPE_SYSTEM = 3; // 0x3
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>";
}
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 3ca147b..04e2fd1 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -1431,6 +1431,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
case TYPE_WALLPAPER:
case TYPE_PRIVATE_PRESENTATION:
case TYPE_VOICE_INTERACTION:
+ case TYPE_ACCESSIBILITY_OVERLAY:
// The window manager will check these.
break;
case TYPE_PHONE:
@@ -1660,15 +1661,18 @@ public class PhoneWindowManager implements WindowManagerPolicy {
// the drag layer: input for drag-and-drop is associated with this window,
// which sits above all other focusable windows
return 25;
- case TYPE_SECURE_SYSTEM_OVERLAY:
+ case TYPE_ACCESSIBILITY_OVERLAY:
+ // overlay put by accessibility services to intercept user interaction
return 26;
- case TYPE_BOOT_PROGRESS:
+ case TYPE_SECURE_SYSTEM_OVERLAY:
return 27;
+ case TYPE_BOOT_PROGRESS:
+ return 28;
case TYPE_POINTER:
// the (mouse) pointer layer
- return 28;
- case TYPE_HIDDEN_NAV_CONSUMER:
return 29;
+ case TYPE_HIDDEN_NAV_CONSUMER:
+ return 30;
}
Log.e(TAG, "Unknown window type: " + type);
return 2;
@@ -1972,7 +1976,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
mKeyguardScrim = win;
break;
-
}
return WindowManagerGlobal.ADD_OKAY;
}
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index e1a74d1..2781890 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -1040,7 +1040,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
private void addServiceLocked(Service service, UserState userState) {
try {
- service.linkToOwnDeathLocked();
+ service.onAdded();
userState.mBoundServices.add(service);
userState.mComponentNameToServiceMap.put(service.mComponentName, service);
} catch (RemoteException re) {
@@ -1056,7 +1056,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
private void removeServiceLocked(Service service, UserState userState) {
userState.mBoundServices.remove(service);
userState.mComponentNameToServiceMap.remove(service.mComponentName);
- service.unlinkToOwnDeathLocked();
+ service.onRemoved();
}
/**
@@ -1931,6 +1931,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
final ResolveInfo mResolveInfo;
+ final IBinder mOverlayWindowToken = new Binder();
+
// the events pending events to be dispatched to this service
final SparseArray<AccessibilityEvent> mPendingEvents =
new SparseArray<>();
@@ -2112,7 +2114,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
userState.mBindingServices.remove(mComponentName);
mWasConnectedAndDied = false;
try {
- mServiceInterface.setConnection(this, mId);
+ mServiceInterface.init(this, mId, mOverlayWindowToken);
onUserStateChangedLocked(userState);
} catch (RemoteException re) {
Slog.w(LOG_TAG, "Error while setting connection for service: "
@@ -2602,6 +2604,27 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
/* do nothing - #binderDied takes care */
}
+ public void onAdded() throws RemoteException {
+ linkToOwnDeathLocked();
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ mWindowManagerService.addWindowToken(mOverlayWindowToken,
+ WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
+ public void onRemoved() {
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ mWindowManagerService.removeWindowToken(mOverlayWindowToken, true);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ unlinkToOwnDeathLocked();
+ }
+
public void linkToOwnDeathLocked() throws RemoteException {
mService.linkToDeath(this, 0);
}
@@ -2614,7 +2637,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
try {
// Clear the proxy in the other process so this
// IAccessibilityServiceConnection can be garbage collected.
- mServiceInterface.setConnection(null, mId);
+ mServiceInterface.init(null, mId, null);
} catch (RemoteException re) {
/* ignore */
}
@@ -3164,6 +3187,10 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
return AccessibilityWindowInfo.TYPE_SYSTEM;
}
+ case WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY: {
+ return AccessibilityWindowInfo.TYPE_ACCESSIBILITY_OVERLAY;
+ }
+
default: {
return -1;
}
diff --git a/services/core/java/com/android/server/wm/AccessibilityController.java b/services/core/java/com/android/server/wm/AccessibilityController.java
index fde703d..f947b6a 100644
--- a/services/core/java/com/android/server/wm/AccessibilityController.java
+++ b/services/core/java/com/android/server/wm/AccessibilityController.java
@@ -992,8 +992,7 @@ final class AccessibilityController {
final int flags = windowState.mAttrs.flags;
- // If the window is not touchable, do not report it but take into account
- // the space it takes since the content behind it cannot be touched.
+ // If the window is not touchable - ignore.
if ((flags & WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE) != 0) {
continue;
}
@@ -1014,9 +1013,14 @@ final class AccessibilityController {
}
}
- // Account for the space this window takes.
- unaccountedSpace.op(boundsInScreen, unaccountedSpace,
- Region.Op.REVERSE_DIFFERENCE);
+ // Account for the space this window takes if the window
+ // is not an accessibility overlay which does not change
+ // the reported windows.
+ if (windowState.mAttrs.type == WindowManager.LayoutParams
+ .TYPE_ACCESSIBILITY_OVERLAY) {
+ unaccountedSpace.op(boundsInScreen, unaccountedSpace,
+ Region.Op.REVERSE_DIFFERENCE);
+ }
// We figured out what is touchable for the entire screen - done.
if (unaccountedSpace.isEmpty()) {
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 57d793f..3fee608 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -2337,6 +2337,11 @@ public class WindowManagerService extends IWindowManager.Stub
+ attrs.token + ". Aborting.");
return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
}
+ if (type == TYPE_ACCESSIBILITY_OVERLAY) {
+ Slog.w(TAG, "Attempted to add Accessibility overlay window with unknown token "
+ + attrs.token + ". Aborting.");
+ return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
+ }
token = new WindowToken(this, attrs.token, -1, false);
addToken = true;
} else if (type >= FIRST_APPLICATION_WINDOW && type <= LAST_APPLICATION_WINDOW) {
@@ -2380,6 +2385,12 @@ public class WindowManagerService extends IWindowManager.Stub
+ attrs.token + ". Aborting.");
return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
}
+ } else if (type == TYPE_ACCESSIBILITY_OVERLAY) {
+ if (token.windowType != TYPE_ACCESSIBILITY_OVERLAY) {
+ Slog.w(TAG, "Attempted to add Accessibility overlay window with bad token "
+ + attrs.token + ". Aborting.");
+ return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
+ }
} else if (token.appWindowToken != null) {
Slog.w(TAG, "Non-null appWindowToken for system window of type=" + type);
// It is not valid to use an app token with other system types; we will
@@ -11627,5 +11638,23 @@ public class WindowManagerService extends IWindowManager.Stub
checkDrawnWindowsLocked();
}
}
+
+ @Override
+ public void addWindowToken(IBinder token, int type) {
+ WindowManagerService.this.addWindowToken(token, type);
+ }
+
+ @Override
+ public void removeWindowToken(IBinder token, boolean removeWindows) {
+ synchronized(mWindowMap) {
+ if (removeWindows) {
+ WindowToken wtoken = mTokenMap.remove(token);
+ if (wtoken != null) {
+ wtoken.removeAllWindows();
+ }
+ }
+ WindowManagerService.this.removeWindowToken(token);
+ }
+ }
}
}
diff --git a/services/core/java/com/android/server/wm/WindowToken.java b/services/core/java/com/android/server/wm/WindowToken.java
index 2267123..1a672e6 100644
--- a/services/core/java/com/android/server/wm/WindowToken.java
+++ b/services/core/java/com/android/server/wm/WindowToken.java
@@ -17,6 +17,7 @@
package com.android.server.wm;
import android.os.IBinder;
+import android.util.Slog;
import java.io.PrintWriter;
@@ -29,7 +30,7 @@ import java.io.PrintWriter;
class WindowToken {
// The window manager!
final WindowManagerService service;
-
+
// The actual token.
final IBinder token;
@@ -77,6 +78,15 @@ class WindowToken {
explicit = _explicit;
}
+ void removeAllWindows() {
+ for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
+ WindowState win = windows.get(winNdx);
+ if (WindowManagerService.DEBUG_WINDOW_MOVEMENT) Slog.w(WindowManagerService.TAG,
+ "removeAllWindows: removing win=" + win);
+ win.mService.removeWindowLocked(win.mSession, win);
+ }
+ }
+
void dump(PrintWriter pw, String prefix) {
pw.print(prefix); pw.print("windows="); pw.println(windows);
pw.print(prefix); pw.print("windowType="); pw.print(windowType);