am a8afa694: Regression in screen introspection APIs due to the multi-user change.

* commit 'a8afa694d6881266ad762aacdac92b2047f9a86c':
  Regression in screen introspection APIs due to the multi-user change.
This commit is contained in:
Svetoslav Ganov
2012-09-25 14:07:33 -07:00
committed by Android Git Automerger

View File

@@ -157,7 +157,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
private final SparseArray<UserState> mUserStates = new SparseArray<UserState>(); private final SparseArray<UserState> mUserStates = new SparseArray<UserState>();
private int mCurrentUserId = UserHandle.USER_NULL; private int mCurrentUserId = UserHandle.USER_OWNER;
private UserState getCurrentUserStateLocked() { private UserState getCurrentUserStateLocked() {
return getUserStateLocked(mCurrentUserId); return getUserStateLocked(mCurrentUserId);
@@ -296,12 +296,19 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
UserState userState = getUserStateLocked(resolvedUserId); UserState userState = getUserStateLocked(resolvedUserId);
if (mSecurityPolicy.isCallerInteractingAcrossUsers(userId)) { if (mSecurityPolicy.isCallerInteractingAcrossUsers(userId)) {
mGlobalClients.register(client); mGlobalClients.register(client);
if (DEBUG) {
Slog.i(LOG_TAG, "Added global client for pid:" + Binder.getCallingPid());
}
return getClientState(userState); return getClientState(userState);
} else { } else {
userState.mClients.register(client); userState.mClients.register(client);
// If this client is not for the current user we do not // If this client is not for the current user we do not
// return a state since it is not for the foreground user. // return a state since it is not for the foreground user.
// We will send the state to the client on a user switch. // We will send the state to the client on a user switch.
if (DEBUG) {
Slog.i(LOG_TAG, "Added user client for pid:" + Binder.getCallingPid()
+ " and userId:" + mCurrentUserId);
}
return (resolvedUserId == mCurrentUserId) ? getClientState(userState) : 0; return (resolvedUserId == mCurrentUserId) ? getClientState(userState) : 0;
} }
} }
@@ -316,7 +323,9 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
return true; // yes, recycle the event return true; // yes, recycle the event
} }
if (mSecurityPolicy.canDispatchAccessibilityEvent(event)) { if (mSecurityPolicy.canDispatchAccessibilityEvent(event)) {
mSecurityPolicy.updateActiveWindowAndEventSourceLocked(event); mSecurityPolicy.updateEventSourceLocked(event);
mMainHandler.obtainMessage(MainHandler.MSG_UPDATE_ACTIVE_WINDOW,
event.getWindowId(), event.getEventType()).sendToTarget();
notifyAccessibilityServicesDelayedLocked(event, false); notifyAccessibilityServicesDelayedLocked(event, false);
notifyAccessibilityServicesDelayedLocked(event, true); notifyAccessibilityServicesDelayedLocked(event, true);
} }
@@ -399,6 +408,10 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
wrapper.linkToDeath(); wrapper.linkToDeath();
mGlobalInteractionConnections.put(windowId, wrapper); mGlobalInteractionConnections.put(windowId, wrapper);
mGlobalWindowTokens.put(windowId, windowToken.asBinder()); mGlobalWindowTokens.put(windowId, windowToken.asBinder());
if (DEBUG) {
Slog.i(LOG_TAG, "Added global connection for pid:" + Binder.getCallingPid()
+ " with windowId: " + windowId);
}
} else { } else {
AccessibilityConnectionWrapper wrapper = new AccessibilityConnectionWrapper( AccessibilityConnectionWrapper wrapper = new AccessibilityConnectionWrapper(
windowId, connection, resolvedUserId); windowId, connection, resolvedUserId);
@@ -406,6 +419,10 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
UserState userState = getUserStateLocked(resolvedUserId); UserState userState = getUserStateLocked(resolvedUserId);
userState.mInteractionConnections.put(windowId, wrapper); userState.mInteractionConnections.put(windowId, wrapper);
userState.mWindowTokens.put(windowId, windowToken.asBinder()); userState.mWindowTokens.put(windowId, windowToken.asBinder());
if (DEBUG) {
Slog.i(LOG_TAG, "Added user connection for pid:" + Binder.getCallingPid()
+ " with windowId: " + windowId + " and userId:" + mCurrentUserId);
}
} }
if (DEBUG) { if (DEBUG) {
Slog.i(LOG_TAG, "Adding interaction connection to windowId: " + windowId); Slog.i(LOG_TAG, "Adding interaction connection to windowId: " + windowId);
@@ -419,26 +436,34 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
mSecurityPolicy.resolveCallingUserIdEnforcingPermissionsLocked( mSecurityPolicy.resolveCallingUserIdEnforcingPermissionsLocked(
UserHandle.getCallingUserId()); UserHandle.getCallingUserId());
IBinder token = window.asBinder(); IBinder token = window.asBinder();
final boolean removedGlobal = final int removedWindowId = removeAccessibilityInteractionConnectionInternalLocked(
removeAccessibilityInteractionConnectionInternalLocked(
token, mGlobalWindowTokens, mGlobalInteractionConnections); token, mGlobalWindowTokens, mGlobalInteractionConnections);
if (removedGlobal) { if (removedWindowId >= 0) {
if (DEBUG) {
Slog.i(LOG_TAG, "Removed global connection for pid:" + Binder.getCallingPid()
+ " with windowId: " + removedWindowId);
}
return; return;
} }
final int userCount = mUserStates.size(); final int userCount = mUserStates.size();
for (int i = 0; i < userCount; i++) { for (int i = 0; i < userCount; i++) {
UserState userState = mUserStates.valueAt(i); UserState userState = mUserStates.valueAt(i);
final boolean removedForUser = final int removedWindowIdForUser =
removeAccessibilityInteractionConnectionInternalLocked( removeAccessibilityInteractionConnectionInternalLocked(
token, userState.mWindowTokens, userState.mInteractionConnections); token, userState.mWindowTokens, userState.mInteractionConnections);
if (removedForUser) { if (removedWindowIdForUser >= 0) {
if (DEBUG) {
Slog.i(LOG_TAG, "Removed user connection for pid:" + Binder.getCallingPid()
+ " with windowId: " + removedWindowIdForUser + " and userId:"
+ mUserStates.keyAt(i));
}
return; return;
} }
} }
} }
} }
private boolean removeAccessibilityInteractionConnectionInternalLocked(IBinder windowToken, private int removeAccessibilityInteractionConnectionInternalLocked(IBinder windowToken,
SparseArray<IBinder> windowTokens, SparseArray<IBinder> windowTokens,
SparseArray<AccessibilityConnectionWrapper> interactionConnections) { SparseArray<AccessibilityConnectionWrapper> interactionConnections) {
final int count = windowTokens.size(); final int count = windowTokens.size();
@@ -449,10 +474,10 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
AccessibilityConnectionWrapper wrapper = interactionConnections.get(windowId); AccessibilityConnectionWrapper wrapper = interactionConnections.get(windowId);
wrapper.unlinkToDeath(); wrapper.unlinkToDeath();
interactionConnections.remove(windowId); interactionConnections.remove(windowId);
return true; return windowId;
} }
} }
return false; return -1;
} }
public void registerUiTestAutomationService(IAccessibilityServiceClient serviceClient, public void registerUiTestAutomationService(IAccessibilityServiceClient serviceClient,
@@ -1160,6 +1185,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
public static final int MSG_SEND_STATE_TO_CLIENTS = 2; public static final int MSG_SEND_STATE_TO_CLIENTS = 2;
public static final int MSG_SEND_CLEARED_STATE_TO_CLIENTS_FOR_USER = 3; public static final int MSG_SEND_CLEARED_STATE_TO_CLIENTS_FOR_USER = 3;
public static final int MSG_SEND_RECREATE_INTERNAL_STATE = 4; public static final int MSG_SEND_RECREATE_INTERNAL_STATE = 4;
public static final int MSG_UPDATE_ACTIVE_WINDOW = 5;
public MainHandler(Looper looper) { public MainHandler(Looper looper) {
super(looper); super(looper);
@@ -1195,6 +1221,11 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
recreateInternalStateLocked(userState); recreateInternalStateLocked(userState);
} }
} break; } break;
case MSG_UPDATE_ACTIVE_WINDOW: {
final int windowId = msg.arg1;
final int eventType = msg.arg2;
mSecurityPolicy.updateActiveWindow(windowId, eventType);
} break;
} }
} }
@@ -2006,14 +2037,18 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
|| event.getWindowId() == mActiveWindowId); || event.getWindowId() == mActiveWindowId);
} }
public void updateActiveWindowAndEventSourceLocked(AccessibilityEvent event) { public void updateEventSourceLocked(AccessibilityEvent event) {
if ((event.getEventType() & RETRIEVAL_ALLOWING_EVENT_TYPES) == 0) {
event.setSource(null);
}
}
public void updateActiveWindow(int windowId, int eventType) {
// The active window is either the window that has input focus or // The active window is either the window that has input focus or
// the window that the user is currently touching. If the user is // the window that the user is currently touching. If the user is
// touching a window that does not have input focus as soon as the // touching a window that does not have input focus as soon as the
// the user stops touching that window the focused window becomes // the user stops touching that window the focused window becomes
// the active one. // the active one.
final int windowId = event.getWindowId();
final int eventType = event.getEventType();
switch (eventType) { switch (eventType) {
case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED: { case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED: {
if (getFocusedWindowId() == windowId) { if (getFocusedWindowId() == windowId) {
@@ -2028,9 +2063,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
mActiveWindowId = getFocusedWindowId(); mActiveWindowId = getFocusedWindowId();
} break; } break;
} }
if ((eventType & RETRIEVAL_ALLOWING_EVENT_TYPES) == 0) {
event.setSource(null);
}
} }
public int getRetrievalAllowingWindowLocked() { public int getRetrievalAllowingWindowLocked() {
@@ -2087,7 +2119,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
public boolean isCallerInteractingAcrossUsers(int userId) { public boolean isCallerInteractingAcrossUsers(int userId) {
final int callingUid = Binder.getCallingUid(); final int callingUid = Binder.getCallingUid();
return (callingUid == Process.SYSTEM_UID return (Binder.getCallingPid() == android.os.Process.myPid()
|| callingUid == Process.SHELL_UID || callingUid == Process.SHELL_UID
|| userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT
|| userId == UserHandle.USER_CURRENT_OR_SELF); || userId == UserHandle.USER_CURRENT_OR_SELF);
@@ -2116,25 +2148,33 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
} }
private int getFocusedWindowId() { private int getFocusedWindowId() {
final long identity = Binder.clearCallingIdentity();
try { try {
// We call this only on window focus change or after touch // We call this only on window focus change or after touch
// exploration gesture end and the shown windows are not that // exploration gesture end and the shown windows are not that
// many, so the linear look up is just fine. // many, so the linear look up is just fine.
IBinder token = mWindowManagerService.getFocusedWindowToken(); IBinder token = mWindowManagerService.getFocusedWindowToken();
if (token != null) { if (token != null) {
SparseArray<IBinder> windows = getCurrentUserStateLocked().mWindowTokens; synchronized (mLock) {
final int windowCount = windows.size(); int windowId = getFocusedWindowIdLocked(token, mGlobalWindowTokens);
for (int i = 0; i < windowCount; i++) { if (windowId < 0) {
if (windows.valueAt(i) == token) { windowId = getFocusedWindowIdLocked(token,
return windows.keyAt(i); getCurrentUserStateLocked().mWindowTokens);
} }
return windowId;
} }
} }
} catch (RemoteException re) { } catch (RemoteException re) {
/* ignore */ /* ignore */
} finally { }
Binder.restoreCallingIdentity(identity); return -1;
}
private int getFocusedWindowIdLocked(IBinder token, SparseArray<IBinder> windows) {
final int windowCount = windows.size();
for (int i = 0; i < windowCount; i++) {
if (windows.valueAt(i) == token) {
return windows.keyAt(i);
}
} }
return -1; return -1;
} }