diff options
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) { |