diff options
| author | 2017-08-22 16:52:12 +0000 | |
|---|---|---|
| committer | 2017-08-22 16:52:12 +0000 | |
| commit | df79ca699d92e41610944a7da36d7d69fbe522dc (patch) | |
| tree | 08297c67a7d31613568eadaf63a4535b1b268f24 | |
| parent | 45ade15a7c7e30b56cad62083421defa607d0e03 (diff) | |
| parent | c6c9e089db3539c74309ad00d1e073c92146d748 (diff) | |
Merge "Place focus on window when a11y performs an action" into oc-mr1-dev
am: c6c9e089db
Change-Id: Iea95db16258ad071852a5925eb69069e432c8e74
5 files changed, 96 insertions, 55 deletions
diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java index 68fb7bc20575..c8d983933fc6 100644 --- a/core/java/android/app/ActivityManagerInternal.java +++ b/core/java/android/app/ActivityManagerInternal.java @@ -262,4 +262,10 @@ public abstract class ActivityManagerInternal { * Clears the previously saved activity manager ANR state. */ public abstract void clearSavedANRState(); + + /** + * Set focus on an activity. + * @param token The IApplicationToken for the activity + */ + public abstract void setFocusedActivity(IBinder token); } diff --git a/core/java/android/view/WindowInfo.java b/core/java/android/view/WindowInfo.java index 95a63944b3bc..bb9e391ddcb4 100644 --- a/core/java/android/view/WindowInfo.java +++ b/core/java/android/view/WindowInfo.java @@ -41,6 +41,7 @@ public class WindowInfo implements Parcelable { public int layer; public IBinder token; public IBinder parentToken; + public IBinder activityToken; public boolean focused; public final Rect boundsInScreen = new Rect(); public List<IBinder> childTokens; @@ -66,6 +67,7 @@ public class WindowInfo implements Parcelable { window.layer = other.layer; window.token = other.token; window.parentToken = other.parentToken; + window.activityToken = other.activityToken; window.focused = other.focused; window.boundsInScreen.set(other.boundsInScreen); window.title = other.title; @@ -99,6 +101,7 @@ public class WindowInfo implements Parcelable { parcel.writeInt(layer); parcel.writeStrongBinder(token); parcel.writeStrongBinder(parentToken); + parcel.writeStrongBinder(activityToken); parcel.writeInt(focused ? 1 : 0); boundsInScreen.writeToParcel(parcel, flags); parcel.writeCharSequence(title); @@ -135,6 +138,7 @@ public class WindowInfo implements Parcelable { layer = parcel.readInt(); token = parcel.readStrongBinder(); parentToken = parcel.readStrongBinder(); + activityToken = parcel.readStrongBinder(); focused = (parcel.readInt() == 1); boundsInScreen.readFromParcel(parcel); title = parcel.readCharSequence(); @@ -155,6 +159,7 @@ public class WindowInfo implements Parcelable { layer = 0; token = null; parentToken = null; + activityToken = null; focused = false; boundsInScreen.setEmpty(); if (childTokens != null) { diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java index a59844d2462b..a97e16be1498 100644 --- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java +++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java @@ -19,6 +19,8 @@ package com.android.server.accessibility; import static android.accessibilityservice.AccessibilityServiceInfo.DEFAULT; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY; +import static android.view.accessibility.AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS; +import static android.view.accessibility.AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS; import android.Manifest; import android.accessibilityservice.AccessibilityService; @@ -27,6 +29,7 @@ import android.accessibilityservice.GestureDescription; import android.accessibilityservice.IAccessibilityServiceClient; import android.accessibilityservice.IAccessibilityServiceConnection; import android.annotation.NonNull; +import android.app.ActivityManagerInternal; import android.app.AlertDialog; import android.app.PendingIntent; import android.app.StatusBarManager; @@ -847,7 +850,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { if (resolvedUserId != mCurrentUserId) { return null; } - if (mSecurityPolicy.findWindowById(windowId) == null) { + if (mSecurityPolicy.findA11yWindowInfoById(windowId) == null) { return null; } IBinder token = mGlobalWindowTokens.get(windowId); @@ -3010,7 +3013,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { if (!permissionGranted) { return null; } - AccessibilityWindowInfo window = mSecurityPolicy.findWindowById(windowId); + AccessibilityWindowInfo window = mSecurityPolicy.findA11yWindowInfoById(windowId); if (window != null) { AccessibilityWindowInfo windowClone = AccessibilityWindowInfo.obtain(window); windowClone.setConnectionId(mId); @@ -3332,31 +3335,30 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { throws RemoteException { final int resolvedWindowId; IAccessibilityInteractionConnection connection = null; + IBinder activityToken = null; synchronized (mLock) { if (!isCalledForCurrentUserLocked()) { return false; } resolvedWindowId = resolveAccessibilityWindowIdLocked(accessibilityWindowId); - final boolean permissionGranted = mSecurityPolicy.canGetAccessibilityNodeInfoLocked( - this, resolvedWindowId); - if (!permissionGranted) { + if (!mSecurityPolicy.canGetAccessibilityNodeInfoLocked(this, resolvedWindowId)) { return false; - } else { - connection = getConnectionLocked(resolvedWindowId); - if (connection == null) { - return false; - } - AccessibilityWindowInfo windowInfo = - mSecurityPolicy.findWindowById(resolvedWindowId); - if ((windowInfo != null) && windowInfo.inPictureInPicture()) { - boolean isA11yFocusAction = - (action == AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS) - || (action == - AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS); - if ((mPictureInPictureActionReplacingConnection != null) - && !isA11yFocusAction) { - connection = mPictureInPictureActionReplacingConnection.mConnection; - } + } + connection = getConnectionLocked(resolvedWindowId); + if (connection == null) return false; + final boolean isA11yFocusAction = (action == ACTION_ACCESSIBILITY_FOCUS) + || (action == ACTION_CLEAR_ACCESSIBILITY_FOCUS); + final AccessibilityWindowInfo a11yWindowInfo = + mSecurityPolicy.findA11yWindowInfoById(resolvedWindowId); + if (!isA11yFocusAction) { + final WindowInfo windowInfo = + mSecurityPolicy.findWindowInfoById(resolvedWindowId); + if (windowInfo != null) activityToken = windowInfo.activityToken; + } + if ((a11yWindowInfo != null) && a11yWindowInfo.inPictureInPicture()) { + if ((mPictureInPictureActionReplacingConnection != null) + && !isA11yFocusAction) { + connection = mPictureInPictureActionReplacingConnection.mConnection; } } } @@ -3368,6 +3370,10 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { mPowerManager.userActivity(SystemClock.uptimeMillis(), PowerManager.USER_ACTIVITY_EVENT_ACCESSIBILITY, 0); + if (activityToken != null) { + LocalServices.getService(ActivityManagerInternal.class) + .setFocusedActivity(activityToken); + } connection.performAccessibilityAction(accessibilityNodeId, action, arguments, interactionId, callback, mFetchFlags, interrogatingPid, interrogatingTid); } catch (RemoteException re) { @@ -4072,7 +4078,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { IAccessibilityInteractionConnectionCallback originalCallback, int resolvedWindowId, int interactionId, int interrogatingPid, long interrogatingTid) { - AccessibilityWindowInfo windowInfo = mSecurityPolicy.findWindowById(resolvedWindowId); + AccessibilityWindowInfo windowInfo = + mSecurityPolicy.findA11yWindowInfoById(resolvedWindowId); if ((windowInfo == null) || !windowInfo.inPictureInPicture() || (mPictureInPictureActionReplacingConnection == null)) { return originalCallback; @@ -4193,24 +4200,12 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { @Override public void onWindowsForAccessibilityChanged(List<WindowInfo> windows) { synchronized (mLock) { - // Populate the windows to report. - List<AccessibilityWindowInfo> reportedWindows = new ArrayList<>(); - final int receivedWindowCount = windows.size(); - for (int i = 0; i < receivedWindowCount; i++) { - WindowInfo receivedWindow = windows.get(i); - AccessibilityWindowInfo reportedWindow = populateReportedWindow( - receivedWindow); - if (reportedWindow != null) { - reportedWindows.add(reportedWindow); - } - } - if (DEBUG) { - Slog.i(LOG_TAG, "Windows changed: " + reportedWindows); + Slog.i(LOG_TAG, "Windows changed: " + windows); } // Let the policy update the focused and active windows. - mSecurityPolicy.updateWindowsLocked(reportedWindows); + mSecurityPolicy.updateWindowsLocked(windows); // Someone may be waiting for the windows - advertise it. mLock.notifyAll(); @@ -4432,7 +4427,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { // In Z order public List<AccessibilityWindowInfo> mWindows; - public SparseArray<AccessibilityWindowInfo> mWindowsById = new SparseArray<>(); + public SparseArray<AccessibilityWindowInfo> mA11yWindowInfoById = new SparseArray<>(); + public SparseArray<WindowInfo> mWindowInfoById = new SparseArray<>(); public int mActiveWindowId = INVALID_WINDOW_ID; public int mFocusedWindowId = INVALID_WINDOW_ID; @@ -4476,14 +4472,14 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { } public void clearWindowsLocked() { - List<AccessibilityWindowInfo> windows = Collections.emptyList(); + List<WindowInfo> windows = Collections.emptyList(); final int activeWindowId = mActiveWindowId; updateWindowsLocked(windows); mActiveWindowId = activeWindowId; mWindows = null; } - public void updateWindowsLocked(List<AccessibilityWindowInfo> windows) { + public void updateWindowsLocked(List<WindowInfo> windows) { if (mWindows == null) { mWindows = new ArrayList<>(); } @@ -4492,7 +4488,12 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { for (int i = oldWindowCount - 1; i >= 0; i--) { mWindows.remove(i).recycle(); } - mWindowsById.clear(); + mA11yWindowInfoById.clear(); + + for (int i = 0; i < mWindowInfoById.size(); i++) { + mWindowInfoById.valueAt(i).recycle(); + } + mWindowInfoById.clear(); mFocusedWindowId = INVALID_WINDOW_ID; if (!mTouchInteractionInProgress) { @@ -4509,19 +4510,25 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { final int windowCount = windows.size(); if (windowCount > 0) { for (int i = 0; i < windowCount; i++) { - AccessibilityWindowInfo window = windows.get(i); - final int windowId = window.getId(); - if (window.isFocused()) { - mFocusedWindowId = windowId; - if (!mTouchInteractionInProgress) { - mActiveWindowId = windowId; - window.setActive(true); - } else if (windowId == mActiveWindowId) { - activeWindowGone = false; + WindowInfo windowInfo = windows.get(i); + AccessibilityWindowInfo window = (mWindowsForAccessibilityCallback != null) + ? mWindowsForAccessibilityCallback.populateReportedWindow(windowInfo) + : null; + if (window != null) { + final int windowId = window.getId(); + if (window.isFocused()) { + mFocusedWindowId = windowId; + if (!mTouchInteractionInProgress) { + mActiveWindowId = windowId; + window.setActive(true); + } else if (windowId == mActiveWindowId) { + activeWindowGone = false; + } } + mWindows.add(window); + mA11yWindowInfoById.put(windowId, window); + mWindowInfoById.put(windowId, WindowInfo.obtain(windowInfo)); } - mWindows.add(window); - mWindowsById.put(windowId, window); } if (mTouchInteractionInProgress && activeWindowGone) { @@ -4530,7 +4537,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { // Focused window may change the active one, so set the // active window once we decided which it is. - for (int i = 0; i < windowCount; i++) { + final int accessibilityWindowCount = mWindows.size(); + for (int i = 0; i < accessibilityWindowCount; i++) { AccessibilityWindowInfo window = mWindows.get(i); if (window.getId() == mActiveWindowId) { window.setActive(true); @@ -4833,11 +4841,15 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { if (windowId == mActiveWindowId) { return true; } - return findWindowById(windowId) != null; + return findA11yWindowInfoById(windowId) != null; + } + + private AccessibilityWindowInfo findA11yWindowInfoById(int windowId) { + return mA11yWindowInfoById.get(windowId); } - private AccessibilityWindowInfo findWindowById(int windowId) { - return mWindowsById.get(windowId); + private WindowInfo findWindowInfoById(int windowId) { + return mWindowInfoById.get(windowId); } private AccessibilityWindowInfo getPictureInPictureWindow() { diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 45387bd4b363..d9f345471f63 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -24101,6 +24101,21 @@ public class ActivityManagerService extends IActivityManager.Stub mLastANRState = null; } } + + @Override + public void setFocusedActivity(IBinder token) { + synchronized (ActivityManagerService.this) { + final ActivityRecord r = ActivityRecord.forTokenLocked(token); + if (r == null) { + throw new IllegalArgumentException( + "setFocusedActivity: No activity record matching token=" + token); + } + if (mStackSupervisor.moveFocusableActivityStackToFrontLocked( + r, "setFocusedActivity")) { + mStackSupervisor.resumeFocusedStackTopActivityLocked(); + } + } + } } /** diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index da739ac93b14..02edd93c499b 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -3972,6 +3972,9 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP windowInfo.type = mAttrs.type; windowInfo.layer = mLayer; windowInfo.token = mClient.asBinder(); + if (mAppToken != null) { + windowInfo.activityToken = mAppToken.appToken.asBinder(); + } windowInfo.title = mAttrs.accessibilityTitle; windowInfo.accessibilityIdOfAnchor = mAttrs.accessibilityIdOfAnchor; windowInfo.focused = isFocused(); |