Loading core/java/android/view/AccessibilityEmbeddedConnection.java 0 → 100644 +81 −0 Original line number Diff line number Diff line /* * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.view; import android.annotation.NonNull; import android.annotation.Nullable; import android.graphics.Matrix; import android.os.IBinder; import android.view.accessibility.AccessibilityManager; import android.view.accessibility.IAccessibilityEmbeddedConnection; import java.lang.ref.WeakReference; /** * This class is an interface this ViewRootImpl provides to the host view to the latter * can interact with the view hierarchy in SurfaceControlViewHost. * * @hide */ final class AccessibilityEmbeddedConnection extends IAccessibilityEmbeddedConnection.Stub { private final WeakReference<ViewRootImpl> mViewRootImpl; AccessibilityEmbeddedConnection(ViewRootImpl viewRootImpl) { mViewRootImpl = new WeakReference<>(viewRootImpl); } @Override public @Nullable IBinder associateEmbeddedHierarchy(@NonNull IBinder host, int hostViewId) { final ViewRootImpl viewRootImpl = mViewRootImpl.get(); if (viewRootImpl != null) { final AccessibilityManager accessibilityManager = AccessibilityManager.getInstance( viewRootImpl.mContext); viewRootImpl.mAttachInfo.mLeashedParentToken = host; viewRootImpl.mAttachInfo.mLeashedParentAccessibilityViewId = hostViewId; if (accessibilityManager.isEnabled()) { accessibilityManager.associateEmbeddedHierarchy(host, viewRootImpl.mLeashToken); } return viewRootImpl.mLeashToken; } return null; } @Override public void disassociateEmbeddedHierarchy() { final ViewRootImpl viewRootImpl = mViewRootImpl.get(); if (viewRootImpl != null) { final AccessibilityManager accessibilityManager = AccessibilityManager.getInstance( viewRootImpl.mContext); viewRootImpl.mAttachInfo.mLeashedParentToken = null; viewRootImpl.mAttachInfo.mLeashedParentAccessibilityViewId = View.NO_ID; viewRootImpl.mAttachInfo.mLocationInParentDisplay.set(0, 0); if (accessibilityManager.isEnabled()) { accessibilityManager.disassociateEmbeddedHierarchy(viewRootImpl.mLeashToken); } } } @Override public void setScreenMatrix(float[] matrixValues) { final ViewRootImpl viewRootImpl = mViewRootImpl.get(); if (viewRootImpl != null) { // TODO(b/148821260): Implement the rest of matrix values. viewRootImpl.mAttachInfo.mLocationInParentDisplay.set( (int) matrixValues[Matrix.MTRANS_X], (int) matrixValues[Matrix.MTRANS_Y]); } } } core/java/android/view/AccessibilityInteractionController.java +32 −0 Original line number Diff line number Diff line Loading @@ -855,6 +855,36 @@ public final class AccessibilityInteractionController { return mViewRootImpl.mAttachInfo.mLocationInParentDisplay.equals(0, 0); } private void associateLeashedParentIfNeeded(List<AccessibilityNodeInfo> infos) { if (infos == null || shouldBypassAssociateLeashedParent()) { return; } final int infoCount = infos.size(); for (int i = 0; i < infoCount; i++) { final AccessibilityNodeInfo info = infos.get(i); associateLeashedParentIfNeeded(info); } } private void associateLeashedParentIfNeeded(AccessibilityNodeInfo info) { if (info == null || shouldBypassAssociateLeashedParent()) { return; } // The node id of root node in embedded maybe not be ROOT_NODE_ID so we compare the id // with root view. if (mViewRootImpl.mView.getAccessibilityViewId() != AccessibilityNodeInfo.getAccessibilityViewId(info.getSourceNodeId())) { return; } info.setLeashedParent(mViewRootImpl.mAttachInfo.mLeashedParentToken, mViewRootImpl.mAttachInfo.mLeashedParentAccessibilityViewId); } private boolean shouldBypassAssociateLeashedParent() { return (mViewRootImpl.mAttachInfo.mLeashedParentToken == null && mViewRootImpl.mAttachInfo.mLeashedParentAccessibilityViewId == View.NO_ID); } private void applyAppScaleAndMagnificationSpecIfNeeded(AccessibilityNodeInfo info, MagnificationSpec spec) { if (info == null) { Loading Loading @@ -914,6 +944,7 @@ public final class AccessibilityInteractionController { MagnificationSpec spec, Region interactiveRegion) { try { mViewRootImpl.mAttachInfo.mAccessibilityFetchFlags = 0; associateLeashedParentIfNeeded(infos); adjustBoundsInScreenIfNeeded(infos); // To avoid applyAppScaleAndMagnificationSpecIfNeeded changing the bounds of node, // then impact the visibility result, we need to adjust visibility before apply scale. Loading @@ -935,6 +966,7 @@ public final class AccessibilityInteractionController { MagnificationSpec spec, Region interactiveRegion) { try { mViewRootImpl.mAttachInfo.mAccessibilityFetchFlags = 0; associateLeashedParentIfNeeded(info); adjustBoundsInScreenIfNeeded(info); // To avoid applyAppScaleAndMagnificationSpecIfNeeded changing the bounds of node, // then impact the visibility result, we need to adjust visibility before apply scale. Loading core/java/android/view/View.java +12 −0 Original line number Diff line number Diff line Loading @@ -28988,6 +28988,18 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ OnContentApplyWindowInsetsListener mContentOnApplyWindowInsetsListener; /** * The leash token of this view's parent when it's in an embedded hierarchy that is * re-parented to another window. */ IBinder mLeashedParentToken; /** * The accessibility view id of this view's parent when it's in an embedded * hierarchy that is re-parented to another window. */ int mLeashedParentAccessibilityViewId; /** * Creates a new set of attachment information with the specified * events handler and thread. core/java/android/view/ViewRootImpl.java +22 −0 Original line number Diff line number Diff line Loading @@ -135,6 +135,7 @@ import android.view.accessibility.AccessibilityNodeInfo; import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction; import android.view.accessibility.AccessibilityNodeProvider; import android.view.accessibility.AccessibilityWindowInfo; import android.view.accessibility.IAccessibilityEmbeddedConnection; import android.view.accessibility.IAccessibilityInteractionConnection; import android.view.accessibility.IAccessibilityInteractionConnectionCallback; import android.view.animation.AccelerateDecelerateInterpolator; Loading Loading @@ -355,6 +356,8 @@ public final class ViewRootImpl implements ViewParent, final W mWindow; final IBinder mLeashToken; final int mTargetSdkVersion; int mSeq; Loading Loading @@ -652,6 +655,8 @@ public final class ViewRootImpl implements ViewParent, private final GestureExclusionTracker mGestureExclusionTracker = new GestureExclusionTracker(); private IAccessibilityEmbeddedConnection mEmbeddedConnection; static final class SystemUiVisibilityInfo { int seq; int globalVisibility; Loading Loading @@ -685,6 +690,7 @@ public final class ViewRootImpl implements ViewParent, mVisRect = new Rect(); mWinFrame = new Rect(); mWindow = new W(this); mLeashToken = new Binder(); mTargetSdkVersion = context.getApplicationInfo().targetSdkVersion; mViewVisibility = View.GONE; mTransparentRegion = new Region(); Loading Loading @@ -9157,6 +9163,10 @@ public final class ViewRootImpl implements ViewParent, focusedView.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED); } } if (mAttachInfo.mLeashedParentToken != null) { mAccessibilityManager.associateEmbeddedHierarchy( mAttachInfo.mLeashedParentToken, mLeashToken); } } else { ensureNoConnection(); mHandler.obtainMessage(MSG_CLEAR_ACCESSIBILITY_FOCUS_HOST).sendToTarget(); Loading @@ -9169,6 +9179,7 @@ public final class ViewRootImpl implements ViewParent, if (!registered) { mAttachInfo.mAccessibilityWindowId = mAccessibilityManager.addAccessibilityInteractionConnection(mWindow, mLeashToken, mContext.getPackageName(), new AccessibilityInteractionConnection(ViewRootImpl.this)); } Loading Loading @@ -9355,6 +9366,17 @@ public final class ViewRootImpl implements ViewParent, } } /** * Gets an accessibility embedded connection interface for this ViewRootImpl. * @hide */ public IAccessibilityEmbeddedConnection getEmbeddedConnection() { if (mEmbeddedConnection == null) { mEmbeddedConnection = new AccessibilityEmbeddedConnection(ViewRootImpl.this); } return mEmbeddedConnection; } private class SendWindowContentChangedAccessibilityEvent implements Runnable { private int mChangeTypes = 0; Loading core/java/android/view/accessibility/AccessibilityManager.java +48 −3 Original line number Diff line number Diff line Loading @@ -1085,6 +1085,50 @@ public final class AccessibilityManager { } } /** * Associate the connection between the host View and the embedded SurfaceControlViewHost. * * @hide */ public void associateEmbeddedHierarchy(@NonNull IBinder host, @NonNull IBinder embedded) { final IAccessibilityManager service; synchronized (mLock) { service = getServiceLocked(); if (service == null) { return; } } try { service.associateEmbeddedHierarchy(host, embedded); } catch (RemoteException e) { return; } } /** * Disassociate the connection between the host View and the embedded SurfaceControlViewHost. * The given token could be either from host side or embedded side. * * @hide */ public void disassociateEmbeddedHierarchy(@NonNull IBinder token) { if (token == null) { return; } final IAccessibilityManager service; synchronized (mLock) { service = getServiceLocked(); if (service == null) { return; } } try { service.disassociateEmbeddedHierarchy(token); } catch (RemoteException e) { return; } } /** * Sets the current state and notifies listeners, if necessary. * Loading Loading @@ -1147,11 +1191,12 @@ public final class AccessibilityManager { /** * Adds an accessibility interaction connection interface for a given window. * @param windowToken The window token to which a connection is added. * @param leashToken The leash token to which a connection is added. * @param connection The connection. * * @hide */ public int addAccessibilityInteractionConnection(IWindow windowToken, public int addAccessibilityInteractionConnection(IWindow windowToken, IBinder leashToken, String packageName, IAccessibilityInteractionConnection connection) { final IAccessibilityManager service; final int userId; Loading @@ -1163,8 +1208,8 @@ public final class AccessibilityManager { userId = mUserId; } try { return service.addAccessibilityInteractionConnection(windowToken, connection, packageName, userId); return service.addAccessibilityInteractionConnection(windowToken, leashToken, connection, packageName, userId); } catch (RemoteException re) { Log.e(LOG_TAG, "Error while adding an accessibility interaction connection. ", re); } Loading Loading
core/java/android/view/AccessibilityEmbeddedConnection.java 0 → 100644 +81 −0 Original line number Diff line number Diff line /* * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.view; import android.annotation.NonNull; import android.annotation.Nullable; import android.graphics.Matrix; import android.os.IBinder; import android.view.accessibility.AccessibilityManager; import android.view.accessibility.IAccessibilityEmbeddedConnection; import java.lang.ref.WeakReference; /** * This class is an interface this ViewRootImpl provides to the host view to the latter * can interact with the view hierarchy in SurfaceControlViewHost. * * @hide */ final class AccessibilityEmbeddedConnection extends IAccessibilityEmbeddedConnection.Stub { private final WeakReference<ViewRootImpl> mViewRootImpl; AccessibilityEmbeddedConnection(ViewRootImpl viewRootImpl) { mViewRootImpl = new WeakReference<>(viewRootImpl); } @Override public @Nullable IBinder associateEmbeddedHierarchy(@NonNull IBinder host, int hostViewId) { final ViewRootImpl viewRootImpl = mViewRootImpl.get(); if (viewRootImpl != null) { final AccessibilityManager accessibilityManager = AccessibilityManager.getInstance( viewRootImpl.mContext); viewRootImpl.mAttachInfo.mLeashedParentToken = host; viewRootImpl.mAttachInfo.mLeashedParentAccessibilityViewId = hostViewId; if (accessibilityManager.isEnabled()) { accessibilityManager.associateEmbeddedHierarchy(host, viewRootImpl.mLeashToken); } return viewRootImpl.mLeashToken; } return null; } @Override public void disassociateEmbeddedHierarchy() { final ViewRootImpl viewRootImpl = mViewRootImpl.get(); if (viewRootImpl != null) { final AccessibilityManager accessibilityManager = AccessibilityManager.getInstance( viewRootImpl.mContext); viewRootImpl.mAttachInfo.mLeashedParentToken = null; viewRootImpl.mAttachInfo.mLeashedParentAccessibilityViewId = View.NO_ID; viewRootImpl.mAttachInfo.mLocationInParentDisplay.set(0, 0); if (accessibilityManager.isEnabled()) { accessibilityManager.disassociateEmbeddedHierarchy(viewRootImpl.mLeashToken); } } } @Override public void setScreenMatrix(float[] matrixValues) { final ViewRootImpl viewRootImpl = mViewRootImpl.get(); if (viewRootImpl != null) { // TODO(b/148821260): Implement the rest of matrix values. viewRootImpl.mAttachInfo.mLocationInParentDisplay.set( (int) matrixValues[Matrix.MTRANS_X], (int) matrixValues[Matrix.MTRANS_Y]); } } }
core/java/android/view/AccessibilityInteractionController.java +32 −0 Original line number Diff line number Diff line Loading @@ -855,6 +855,36 @@ public final class AccessibilityInteractionController { return mViewRootImpl.mAttachInfo.mLocationInParentDisplay.equals(0, 0); } private void associateLeashedParentIfNeeded(List<AccessibilityNodeInfo> infos) { if (infos == null || shouldBypassAssociateLeashedParent()) { return; } final int infoCount = infos.size(); for (int i = 0; i < infoCount; i++) { final AccessibilityNodeInfo info = infos.get(i); associateLeashedParentIfNeeded(info); } } private void associateLeashedParentIfNeeded(AccessibilityNodeInfo info) { if (info == null || shouldBypassAssociateLeashedParent()) { return; } // The node id of root node in embedded maybe not be ROOT_NODE_ID so we compare the id // with root view. if (mViewRootImpl.mView.getAccessibilityViewId() != AccessibilityNodeInfo.getAccessibilityViewId(info.getSourceNodeId())) { return; } info.setLeashedParent(mViewRootImpl.mAttachInfo.mLeashedParentToken, mViewRootImpl.mAttachInfo.mLeashedParentAccessibilityViewId); } private boolean shouldBypassAssociateLeashedParent() { return (mViewRootImpl.mAttachInfo.mLeashedParentToken == null && mViewRootImpl.mAttachInfo.mLeashedParentAccessibilityViewId == View.NO_ID); } private void applyAppScaleAndMagnificationSpecIfNeeded(AccessibilityNodeInfo info, MagnificationSpec spec) { if (info == null) { Loading Loading @@ -914,6 +944,7 @@ public final class AccessibilityInteractionController { MagnificationSpec spec, Region interactiveRegion) { try { mViewRootImpl.mAttachInfo.mAccessibilityFetchFlags = 0; associateLeashedParentIfNeeded(infos); adjustBoundsInScreenIfNeeded(infos); // To avoid applyAppScaleAndMagnificationSpecIfNeeded changing the bounds of node, // then impact the visibility result, we need to adjust visibility before apply scale. Loading @@ -935,6 +966,7 @@ public final class AccessibilityInteractionController { MagnificationSpec spec, Region interactiveRegion) { try { mViewRootImpl.mAttachInfo.mAccessibilityFetchFlags = 0; associateLeashedParentIfNeeded(info); adjustBoundsInScreenIfNeeded(info); // To avoid applyAppScaleAndMagnificationSpecIfNeeded changing the bounds of node, // then impact the visibility result, we need to adjust visibility before apply scale. Loading
core/java/android/view/View.java +12 −0 Original line number Diff line number Diff line Loading @@ -28988,6 +28988,18 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ OnContentApplyWindowInsetsListener mContentOnApplyWindowInsetsListener; /** * The leash token of this view's parent when it's in an embedded hierarchy that is * re-parented to another window. */ IBinder mLeashedParentToken; /** * The accessibility view id of this view's parent when it's in an embedded * hierarchy that is re-parented to another window. */ int mLeashedParentAccessibilityViewId; /** * Creates a new set of attachment information with the specified * events handler and thread.
core/java/android/view/ViewRootImpl.java +22 −0 Original line number Diff line number Diff line Loading @@ -135,6 +135,7 @@ import android.view.accessibility.AccessibilityNodeInfo; import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction; import android.view.accessibility.AccessibilityNodeProvider; import android.view.accessibility.AccessibilityWindowInfo; import android.view.accessibility.IAccessibilityEmbeddedConnection; import android.view.accessibility.IAccessibilityInteractionConnection; import android.view.accessibility.IAccessibilityInteractionConnectionCallback; import android.view.animation.AccelerateDecelerateInterpolator; Loading Loading @@ -355,6 +356,8 @@ public final class ViewRootImpl implements ViewParent, final W mWindow; final IBinder mLeashToken; final int mTargetSdkVersion; int mSeq; Loading Loading @@ -652,6 +655,8 @@ public final class ViewRootImpl implements ViewParent, private final GestureExclusionTracker mGestureExclusionTracker = new GestureExclusionTracker(); private IAccessibilityEmbeddedConnection mEmbeddedConnection; static final class SystemUiVisibilityInfo { int seq; int globalVisibility; Loading Loading @@ -685,6 +690,7 @@ public final class ViewRootImpl implements ViewParent, mVisRect = new Rect(); mWinFrame = new Rect(); mWindow = new W(this); mLeashToken = new Binder(); mTargetSdkVersion = context.getApplicationInfo().targetSdkVersion; mViewVisibility = View.GONE; mTransparentRegion = new Region(); Loading Loading @@ -9157,6 +9163,10 @@ public final class ViewRootImpl implements ViewParent, focusedView.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED); } } if (mAttachInfo.mLeashedParentToken != null) { mAccessibilityManager.associateEmbeddedHierarchy( mAttachInfo.mLeashedParentToken, mLeashToken); } } else { ensureNoConnection(); mHandler.obtainMessage(MSG_CLEAR_ACCESSIBILITY_FOCUS_HOST).sendToTarget(); Loading @@ -9169,6 +9179,7 @@ public final class ViewRootImpl implements ViewParent, if (!registered) { mAttachInfo.mAccessibilityWindowId = mAccessibilityManager.addAccessibilityInteractionConnection(mWindow, mLeashToken, mContext.getPackageName(), new AccessibilityInteractionConnection(ViewRootImpl.this)); } Loading Loading @@ -9355,6 +9366,17 @@ public final class ViewRootImpl implements ViewParent, } } /** * Gets an accessibility embedded connection interface for this ViewRootImpl. * @hide */ public IAccessibilityEmbeddedConnection getEmbeddedConnection() { if (mEmbeddedConnection == null) { mEmbeddedConnection = new AccessibilityEmbeddedConnection(ViewRootImpl.this); } return mEmbeddedConnection; } private class SendWindowContentChangedAccessibilityEvent implements Runnable { private int mChangeTypes = 0; Loading
core/java/android/view/accessibility/AccessibilityManager.java +48 −3 Original line number Diff line number Diff line Loading @@ -1085,6 +1085,50 @@ public final class AccessibilityManager { } } /** * Associate the connection between the host View and the embedded SurfaceControlViewHost. * * @hide */ public void associateEmbeddedHierarchy(@NonNull IBinder host, @NonNull IBinder embedded) { final IAccessibilityManager service; synchronized (mLock) { service = getServiceLocked(); if (service == null) { return; } } try { service.associateEmbeddedHierarchy(host, embedded); } catch (RemoteException e) { return; } } /** * Disassociate the connection between the host View and the embedded SurfaceControlViewHost. * The given token could be either from host side or embedded side. * * @hide */ public void disassociateEmbeddedHierarchy(@NonNull IBinder token) { if (token == null) { return; } final IAccessibilityManager service; synchronized (mLock) { service = getServiceLocked(); if (service == null) { return; } } try { service.disassociateEmbeddedHierarchy(token); } catch (RemoteException e) { return; } } /** * Sets the current state and notifies listeners, if necessary. * Loading Loading @@ -1147,11 +1191,12 @@ public final class AccessibilityManager { /** * Adds an accessibility interaction connection interface for a given window. * @param windowToken The window token to which a connection is added. * @param leashToken The leash token to which a connection is added. * @param connection The connection. * * @hide */ public int addAccessibilityInteractionConnection(IWindow windowToken, public int addAccessibilityInteractionConnection(IWindow windowToken, IBinder leashToken, String packageName, IAccessibilityInteractionConnection connection) { final IAccessibilityManager service; final int userId; Loading @@ -1163,8 +1208,8 @@ public final class AccessibilityManager { userId = mUserId; } try { return service.addAccessibilityInteractionConnection(windowToken, connection, packageName, userId); return service.addAccessibilityInteractionConnection(windowToken, leashToken, connection, packageName, userId); } catch (RemoteException re) { Log.e(LOG_TAG, "Error while adding an accessibility interaction connection. ", re); } Loading