summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/java/android/view/Window.java2
-rw-r--r--services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java27
-rw-r--r--services/core/java/com/android/server/wm/AccessibilityController.java66
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java20
4 files changed, 47 insertions, 68 deletions
diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java
index 2e5c1e0..6944c53 100644
--- a/core/java/android/view/Window.java
+++ b/core/java/android/view/Window.java
@@ -364,7 +364,7 @@ public abstract class Window {
/**
* This hook is called whenever the window focus changes. See
* {@link View#onWindowFocusChanged(boolean)
- * View.onWindowFocusChanged(boolean)} for more information.
+ * View.onWindowFocusChangedNotLocked(boolean)} for more information.
*
* @param hasFocus Whether the window now has focus.
*/
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index 2781890..89aebe8 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -3314,8 +3314,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
public int mAccessibilityFocusedWindowId = INVALID_WINDOW_ID;
public long mAccessibilityFocusNodeId = AccessibilityNodeInfo.UNDEFINED_ITEM_ID;
- public AccessibilityEvent mShowingFocusedWindowEvent;
-
private boolean mTouchInteractionInProgress;
private boolean canDispatchAccessibilityEventLocked(AccessibilityEvent event) {
@@ -3324,19 +3322,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
// All events that are for changes in a global window
// state should *always* be dispatched.
case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED:
- if (mWindowsForAccessibilityCallback != null) {
- // OK, this is fun. Sometimes the focused window is notified
- // it has focus before being shown. Historically this event
- // means that the window is focused and can be introspected.
- // But we still have not gotten the window state from the
- // window manager, so delay the notification until then.
- AccessibilityWindowInfo window = findWindowById(event.getWindowId());
- if (window == null) {
- mShowingFocusedWindowEvent = AccessibilityEvent.obtain(event);
- return false;
- }
- }
- // $fall-through$
case AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED:
case AccessibilityEvent.TYPE_ANNOUNCEMENT:
// All events generated by the user touching the
@@ -3428,18 +3413,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
}
notifyWindowsChanged();
-
- // If we are delaying a window state change event as the window
- // source was showing when it was fired, now is the time to send.
- if (mShowingFocusedWindowEvent != null) {
- final int windowId = mShowingFocusedWindowEvent.getWindowId();
- AccessibilityWindowInfo window = findWindowById(windowId);
- if (window != null) {
- // Sending does the recycle.
- sendAccessibilityEvent(mShowingFocusedWindowEvent, mCurrentUserId);
- }
- mShowingFocusedWindowEvent = null;
- }
}
public boolean computePartialInteractiveRegionForWindowLocked(int windowId,
diff --git a/services/core/java/com/android/server/wm/AccessibilityController.java b/services/core/java/com/android/server/wm/AccessibilityController.java
index 0cbf03a..08754f9 100644
--- a/services/core/java/com/android/server/wm/AccessibilityController.java
+++ b/services/core/java/com/android/server/wm/AccessibilityController.java
@@ -159,11 +159,15 @@ final class AccessibilityController {
}
}
- public void onWindowFocusChangedLocked() {
+ public void onWindowFocusChangedNotLocked() {
// Not relevant for the display magnifier.
- if (mWindowsForAccessibilityObserver != null) {
- mWindowsForAccessibilityObserver.scheduleComputeChangedWindowsLocked();
+ WindowsForAccessibilityObserver observer = null;
+ synchronized (mWindowManagerService) {
+ observer = mWindowsForAccessibilityObserver;
+ }
+ if (observer != null) {
+ observer.performComputeChangedWindowsNotLocked();
}
}
@@ -937,14 +941,13 @@ final class AccessibilityController {
computeChangedWindows();
}
+ public void performComputeChangedWindowsNotLocked() {
+ mHandler.removeMessages(MyHandler.MESSAGE_COMPUTE_CHANGED_WINDOWS);
+ computeChangedWindows();
+ }
+
public void scheduleComputeChangedWindowsLocked() {
- // If focus changed, compute changed windows immediately as the focused window
- // is used by the accessibility manager service to determine the active window.
- if (mWindowManagerService.mCurrentFocus != null
- && mWindowManagerService.mCurrentFocus != mWindowManagerService.mLastFocus) {
- mHandler.removeMessages(MyHandler.MESSAGE_COMPUTE_CHANGED_WINDOWS);
- computeChangedWindows();
- } else if (!mHandler.hasMessages(MyHandler.MESSAGE_COMPUTE_CHANGED_WINDOWS)) {
+ if (!mHandler.hasMessages(MyHandler.MESSAGE_COMPUTE_CHANGED_WINDOWS)) {
mHandler.sendEmptyMessageDelayed(MyHandler.MESSAGE_COMPUTE_CHANGED_WINDOWS,
mRecurringAccessibilityEventsIntervalMillis);
}
@@ -955,6 +958,9 @@ final class AccessibilityController {
Slog.i(LOG_TAG, "computeChangedWindows()");
}
+ boolean windowsChanged = false;
+ List<WindowInfo> windows = new ArrayList<WindowInfo>();
+
synchronized (mWindowManagerService.mWindowMap) {
// Do not send the windows if there is no current focus as
// the window manager is still looking for where to put it.
@@ -975,8 +981,6 @@ final class AccessibilityController {
SparseArray<WindowState> visibleWindows = mTempWindowStates;
populateVisibleWindowsOnScreenLocked(visibleWindows);
- List<WindowInfo> windows = new ArrayList<WindowInfo>();
-
Set<IBinder> addedWindows = mTempBinderSet;
addedWindows.clear();
@@ -1074,7 +1078,6 @@ final class AccessibilityController {
addedWindows.clear();
// We computed the windows and if they changed notify the client.
- boolean windowsChanged = false;
if (mOldWindows.size() != windows.size()) {
// Different size means something changed.
windowsChanged = true;
@@ -1096,22 +1099,24 @@ final class AccessibilityController {
}
if (windowsChanged) {
- if (DEBUG) {
- Log.i(LOG_TAG, "Windows changed:" + windows);
- }
- // Remember the old windows to detect changes.
cacheWindows(windows);
- // Announce the change.
- mHandler.obtainMessage(MyHandler.MESSAGE_NOTIFY_WINDOWS_CHANGED,
- windows).sendToTarget();
- } else {
- if (DEBUG) {
- Log.i(LOG_TAG, "No windows changed.");
- }
- // Recycle the nodes as we do not need them.
- clearAndRecycleWindows(windows);
}
}
+
+ // Now we do not hold the lock, so send the windows over.
+ if (windowsChanged) {
+ if (DEBUG) {
+ Log.i(LOG_TAG, "Windows changed:" + windows);
+ }
+ mCallback.onWindowsForAccessibilityChanged(windows);
+ } else {
+ if (DEBUG) {
+ Log.i(LOG_TAG, "No windows changed.");
+ }
+ }
+
+ // Recycle the windows as we do not need them.
+ clearAndRecycleWindows(windows);
}
private void computeWindowBoundsInScreen(WindowState windowState, Rect outBounds) {
@@ -1217,7 +1222,7 @@ final class AccessibilityController {
return false;
}
- private void clearAndRecycleWindows(List<WindowInfo> windows) {
+ private static void clearAndRecycleWindows(List<WindowInfo> windows) {
final int windowCount = windows.size();
for (int i = windowCount - 1; i >= 0; i--) {
windows.remove(i).recycle();
@@ -1254,7 +1259,6 @@ final class AccessibilityController {
private class MyHandler extends Handler {
public static final int MESSAGE_COMPUTE_CHANGED_WINDOWS = 1;
- public static final int MESSAGE_NOTIFY_WINDOWS_CHANGED = 2;
public MyHandler(Looper looper) {
super(looper, null, false);
@@ -1267,12 +1271,6 @@ final class AccessibilityController {
case MESSAGE_COMPUTE_CHANGED_WINDOWS: {
computeChangedWindows();
} break;
-
- case MESSAGE_NOTIFY_WINDOWS_CHANGED: {
- List<WindowInfo> windows = (List<WindowInfo>) message.obj;
- mCallback.onWindowsForAccessibilityChanged(windows);
- clearAndRecycleWindows(windows);
- } break;
}
}
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index b7857e1..2750941 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -7610,7 +7610,15 @@ public class WindowManagerService extends IWindowManager.Stub
WindowState lastFocus;
WindowState newFocus;
+ AccessibilityController accessibilityController = null;
+
synchronized(mWindowMap) {
+ // TODO(multidisplay): Accessibility supported only of default desiplay.
+ if (mAccessibilityController != null && getDefaultDisplayContentLocked()
+ .getDisplayId() == Display.DEFAULT_DISPLAY) {
+ accessibilityController = mAccessibilityController;
+ }
+
lastFocus = mLastFocus;
newFocus = mCurrentFocus;
if (lastFocus == newFocus) {
@@ -7628,6 +7636,12 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
+ // First notify the accessibility manager for the change so it has
+ // the windows before the newly focused one starts firing eventgs.
+ if (accessibilityController != null) {
+ accessibilityController.onWindowFocusChangedNotLocked();
+ }
+
//System.out.println("Changing focus from " + lastFocus
// + " to " + newFocus);
if (newFocus != null) {
@@ -10402,12 +10416,6 @@ public class WindowManagerService extends IWindowManager.Stub
mCurrentFocus = newFocus;
mLosingFocus.remove(newFocus);
- // TODO(multidisplay): Accessibilty supported only of default desiplay.
- if (mAccessibilityController != null
- && displayContent.getDisplayId() == Display.DEFAULT_DISPLAY) {
- mAccessibilityController.onWindowFocusChangedLocked();
- }
-
int focusChanged = mPolicy.focusChangedLw(oldFocus, newFocus);
if (imWindowChanged && oldFocus != mInputMethodWindow) {