am bd6fabe2: Merge "APIs for an accessibility service to put interaction tracking overlays." into lmp-mr1-dev
automerge: 89e7ffe
* commit '89e7ffedadd20a3091e72b42f86c500452df193c':
APIs for an accessibility service to put interaction tracking overlays.
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -541,6 +541,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.
|
||||
*/
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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>";
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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()) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user