Loading core/java/android/view/SurfaceControlViewHost.java +22 −4 Original line number Original line Diff line number Diff line Loading @@ -24,6 +24,7 @@ import android.graphics.PixelFormat; import android.os.IBinder; import android.os.IBinder; import android.os.Parcel; import android.os.Parcel; import android.os.Parcelable; import android.os.Parcelable; import android.view.accessibility.IAccessibilityEmbeddedConnection; /** /** * Utility class for adding a View hierarchy to a {@link SurfaceControl}. The View hierarchy * Utility class for adding a View hierarchy to a {@link SurfaceControl}. The View hierarchy Loading @@ -40,6 +41,7 @@ public class SurfaceControlViewHost { private WindowlessWindowManager mWm; private WindowlessWindowManager mWm; private SurfaceControl mSurfaceControl; private SurfaceControl mSurfaceControl; private IAccessibilityEmbeddedConnection mAccessibilityEmbeddedConnection; /** /** * Package encapsulating a Surface hierarchy which contains interactive view * Package encapsulating a Surface hierarchy which contains interactive view Loading @@ -49,15 +51,18 @@ public class SurfaceControlViewHost { */ */ public static final class SurfacePackage implements Parcelable { public static final class SurfacePackage implements Parcelable { private final SurfaceControl mSurfaceControl; private final SurfaceControl mSurfaceControl; // TODO: Accessibility ID goes here private final IAccessibilityEmbeddedConnection mAccessibilityEmbeddedConnection; SurfacePackage(SurfaceControl sc) { SurfacePackage(SurfaceControl sc, IAccessibilityEmbeddedConnection connection) { mSurfaceControl = sc; mSurfaceControl = sc; mAccessibilityEmbeddedConnection = connection; } } private SurfacePackage(Parcel in) { private SurfacePackage(Parcel in) { mSurfaceControl = new SurfaceControl(); mSurfaceControl = new SurfaceControl(); mSurfaceControl.readFromParcel(in); mSurfaceControl.readFromParcel(in); mAccessibilityEmbeddedConnection = IAccessibilityEmbeddedConnection.Stub.asInterface( in.readStrongBinder()); } } /** /** Loading @@ -69,6 +74,16 @@ public class SurfaceControlViewHost { return mSurfaceControl; return mSurfaceControl; } } /** * Gets an accessibility embedded connection interface for this SurfaceControlViewHost. * * @return {@link IAccessibilityEmbeddedConnection} interface. * @hide */ public IAccessibilityEmbeddedConnection getAccessibilityEmbeddedConnection() { return mAccessibilityEmbeddedConnection; } @Override @Override public int describeContents() { public int describeContents() { return 0; return 0; Loading @@ -77,6 +92,7 @@ public class SurfaceControlViewHost { @Override @Override public void writeToParcel(@NonNull Parcel out, int flags) { public void writeToParcel(@NonNull Parcel out, int flags) { mSurfaceControl.writeToParcel(out, flags); mSurfaceControl.writeToParcel(out, flags); out.writeStrongBinder(mAccessibilityEmbeddedConnection.asBinder()); } } public static final @NonNull Creator<SurfacePackage> CREATOR public static final @NonNull Creator<SurfacePackage> CREATOR Loading @@ -95,6 +111,7 @@ public class SurfaceControlViewHost { @NonNull WindowlessWindowManager wwm) { @NonNull WindowlessWindowManager wwm) { mWm = wwm; mWm = wwm; mViewRoot = new ViewRootImpl(c, d, mWm); mViewRoot = new ViewRootImpl(c, d, mWm); mAccessibilityEmbeddedConnection = mViewRoot.getAccessibilityEmbeddedConnection(); } } /** /** Loading @@ -118,6 +135,7 @@ public class SurfaceControlViewHost { mWm = new WindowlessWindowManager(context.getResources().getConfiguration(), mWm = new WindowlessWindowManager(context.getResources().getConfiguration(), mSurfaceControl, hostToken); mSurfaceControl, hostToken); mViewRoot = new ViewRootImpl(context, display, mWm); mViewRoot = new ViewRootImpl(context, display, mWm); mAccessibilityEmbeddedConnection = mViewRoot.getAccessibilityEmbeddedConnection(); } } /** /** Loading @@ -128,8 +146,8 @@ public class SurfaceControlViewHost { * are linked. * are linked. */ */ public @Nullable SurfacePackage getSurfacePackage() { public @Nullable SurfacePackage getSurfacePackage() { if (mSurfaceControl != null) { if (mSurfaceControl != null && mAccessibilityEmbeddedConnection != null) { return new SurfacePackage(mSurfaceControl); return new SurfacePackage(mSurfaceControl, mAccessibilityEmbeddedConnection); } else { } else { return null; return null; } } Loading core/java/android/view/SurfaceView.java +127 −16 Original line number Original line Diff line number Diff line Loading @@ -28,6 +28,7 @@ import android.content.res.CompatibilityInfo.Translator; import android.graphics.BlendMode; import android.graphics.BlendMode; import android.graphics.Canvas; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Color; import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.Paint; import android.graphics.PixelFormat; import android.graphics.PixelFormat; import android.graphics.PorterDuff; import android.graphics.PorterDuff; Loading @@ -38,12 +39,14 @@ import android.os.Build; import android.os.Handler; import android.os.Handler; import android.os.IBinder; import android.os.IBinder; import android.os.Looper; import android.os.Looper; import android.os.RemoteException; import android.os.SystemClock; import android.os.SystemClock; import android.util.AttributeSet; import android.util.AttributeSet; import android.util.Log; import android.util.Log; import android.view.SurfaceControl.Transaction; import android.view.SurfaceControl.Transaction; import android.view.SurfaceControlViewHost; import android.view.SurfaceControlViewHost; import android.view.accessibility.AccessibilityNodeInfo; import android.view.accessibility.AccessibilityNodeInfo; import android.view.accessibility.IAccessibilityEmbeddedConnection; import com.android.internal.view.SurfaceCallbackHelper; import com.android.internal.view.SurfaceCallbackHelper; Loading Loading @@ -203,8 +206,12 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall private SurfaceControl.Transaction mTmpTransaction = new SurfaceControl.Transaction(); private SurfaceControl.Transaction mTmpTransaction = new SurfaceControl.Transaction(); private int mParentSurfaceGenerationId; private int mParentSurfaceGenerationId; // The token of embedded windowless view hierarchy. private RemoteAccessibilityEmbeddedConnection mRemoteAccessibilityEmbeddedConnection; private IBinder mEmbeddedViewHierarchy; private final Matrix mScreenMatrixForEmbeddedHierarchy = new Matrix(); private final Matrix mTmpMatrix = new Matrix(); private final float[] mMatrixValues = new float[9]; SurfaceControlViewHost.SurfacePackage mSurfacePackage; SurfaceControlViewHost.SurfacePackage mSurfacePackage; public SurfaceView(Context context) { public SurfaceView(Context context) { Loading Loading @@ -923,6 +930,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall } } mTmpTransaction.apply(); mTmpTransaction.apply(); updateScreenMatrixForEmbeddedHierarchy(); if (sizeChanged || creating) { if (sizeChanged || creating) { redrawNeeded = true; redrawNeeded = true; Loading Loading @@ -1510,6 +1518,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall @Override @Override public void surfaceDestroyed() { public void surfaceDestroyed() { setWindowStopped(true); setWindowStopped(true); setRemoteAccessibilityEmbeddedConnection(null, null); } } /** /** Loading Loading @@ -1568,31 +1577,133 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall private void reparentSurfacePackage(SurfaceControl.Transaction t, private void reparentSurfacePackage(SurfaceControl.Transaction t, SurfaceControlViewHost.SurfacePackage p) { SurfaceControlViewHost.SurfacePackage p) { // TODO: Link accessibility IDs here. initEmbeddedHierarchyForAccessibility(p); final SurfaceControl sc = p.getSurfaceControl(); final SurfaceControl sc = p.getSurfaceControl(); t.reparent(sc, mSurfaceControl).show(sc); t.reparent(sc, mSurfaceControl).show(sc); } } /** * Add the token of embedded view hierarchy. Set {@code null} to clear the embedded view * hierarchy. * * @param token IBinder token. * @hide */ public void setEmbeddedViewHierarchy(IBinder token) { mEmbeddedViewHierarchy = token; } /** @hide */ /** @hide */ @Override @Override public void onInitializeAccessibilityNodeInfoInternal(AccessibilityNodeInfo info) { public void onInitializeAccessibilityNodeInfoInternal(AccessibilityNodeInfo info) { super.onInitializeAccessibilityNodeInfoInternal(info); super.onInitializeAccessibilityNodeInfoInternal(info); if (mEmbeddedViewHierarchy == null) { final RemoteAccessibilityEmbeddedConnection wrapper = getRemoteAccessibilityEmbeddedConnection(); if (wrapper == null) { return; return; } } // Add a leashed child when this SurfaceView embeds another view hierarchy. Getting this // Add a leashed child when this SurfaceView embeds another view hierarchy. Getting this // leashed child would return the root node in the embedded hierarchy // leashed child would return the root node in the embedded hierarchy info.addChild(mEmbeddedViewHierarchy); info.addChild(wrapper.getLeashToken()); } private void initEmbeddedHierarchyForAccessibility(SurfaceControlViewHost.SurfacePackage p) { final IAccessibilityEmbeddedConnection connection = p.getAccessibilityEmbeddedConnection(); final RemoteAccessibilityEmbeddedConnection wrapper = getRemoteAccessibilityEmbeddedConnection(); // Do nothing if package is embedding the same view hierarchy. if (wrapper != null && wrapper.getConnection().equals(connection)) { return; } // If this SurfaceView embeds a different view hierarchy, unlink the previous one first. setRemoteAccessibilityEmbeddedConnection(null, null); try { final IBinder leashToken = connection.associateEmbeddedHierarchy( getViewRootImpl().mLeashToken, getAccessibilityViewId()); setRemoteAccessibilityEmbeddedConnection(connection, leashToken); } catch (RemoteException e) { Log.d(TAG, "Error while associateEmbeddedHierarchy " + e); } updateScreenMatrixForEmbeddedHierarchy(); } private void setRemoteAccessibilityEmbeddedConnection( IAccessibilityEmbeddedConnection connection, IBinder leashToken) { try { if (mRemoteAccessibilityEmbeddedConnection != null) { mRemoteAccessibilityEmbeddedConnection.getConnection() .disassociateEmbeddedHierarchy(); mRemoteAccessibilityEmbeddedConnection.unlinkToDeath(); mRemoteAccessibilityEmbeddedConnection = null; } if (connection != null && leashToken != null) { mRemoteAccessibilityEmbeddedConnection = new RemoteAccessibilityEmbeddedConnection(connection, leashToken); mRemoteAccessibilityEmbeddedConnection.linkToDeath(); } } catch (RemoteException e) { Log.d(TAG, "Error while setRemoteEmbeddedConnection " + e); } } private RemoteAccessibilityEmbeddedConnection getRemoteAccessibilityEmbeddedConnection() { return mRemoteAccessibilityEmbeddedConnection; } private void updateScreenMatrixForEmbeddedHierarchy() { mTmpMatrix.reset(); mTmpMatrix.setTranslate(mScreenRect.left, mScreenRect.top); mTmpMatrix.postScale(mScreenRect.width() / (float) mSurfaceWidth, mScreenRect.height() / (float) mSurfaceHeight); // If the screen matrix is identity or doesn't change, do nothing. if (mTmpMatrix.isIdentity() || mTmpMatrix.equals(mScreenMatrixForEmbeddedHierarchy)) { return; } try { final RemoteAccessibilityEmbeddedConnection wrapper = getRemoteAccessibilityEmbeddedConnection(); if (wrapper == null) { return; } mTmpMatrix.getValues(mMatrixValues); wrapper.getConnection().setScreenMatrix(mMatrixValues); mScreenMatrixForEmbeddedHierarchy.set(mTmpMatrix); } catch (RemoteException e) { Log.d(TAG, "Error while setScreenMatrix " + e); } } /** * Wrapper of accessibility embedded connection for embedded view hierarchy. */ private final class RemoteAccessibilityEmbeddedConnection implements IBinder.DeathRecipient { private final IAccessibilityEmbeddedConnection mConnection; private final IBinder mLeashToken; RemoteAccessibilityEmbeddedConnection(IAccessibilityEmbeddedConnection connection, IBinder leashToken) { mConnection = connection; mLeashToken = leashToken; } IAccessibilityEmbeddedConnection getConnection() { return mConnection; } IBinder getLeashToken() { return mLeashToken; } void linkToDeath() throws RemoteException { mConnection.asBinder().linkToDeath(this, 0); } void unlinkToDeath() { mConnection.asBinder().unlinkToDeath(this, 0); } @Override public void binderDied() { unlinkToDeath(); runOnUiThread(() -> { if (mRemoteAccessibilityEmbeddedConnection == this) { mRemoteAccessibilityEmbeddedConnection = null; } }); } } } } } core/java/android/view/ViewRootImpl.java +6 −5 Original line number Original line Diff line number Diff line Loading @@ -655,7 +655,7 @@ public final class ViewRootImpl implements ViewParent, private final GestureExclusionTracker mGestureExclusionTracker = new GestureExclusionTracker(); private final GestureExclusionTracker mGestureExclusionTracker = new GestureExclusionTracker(); private IAccessibilityEmbeddedConnection mEmbeddedConnection; private IAccessibilityEmbeddedConnection mAccessibilityEmbeddedConnection; static final class SystemUiVisibilityInfo { static final class SystemUiVisibilityInfo { int seq; int seq; Loading Loading @@ -9370,11 +9370,12 @@ public final class ViewRootImpl implements ViewParent, * Gets an accessibility embedded connection interface for this ViewRootImpl. * Gets an accessibility embedded connection interface for this ViewRootImpl. * @hide * @hide */ */ public IAccessibilityEmbeddedConnection getEmbeddedConnection() { public IAccessibilityEmbeddedConnection getAccessibilityEmbeddedConnection() { if (mEmbeddedConnection == null) { if (mAccessibilityEmbeddedConnection == null) { mEmbeddedConnection = new AccessibilityEmbeddedConnection(ViewRootImpl.this); mAccessibilityEmbeddedConnection = new AccessibilityEmbeddedConnection( ViewRootImpl.this); } } return mEmbeddedConnection; return mAccessibilityEmbeddedConnection; } } private class SendWindowContentChangedAccessibilityEvent implements Runnable { private class SendWindowContentChangedAccessibilityEvent implements Runnable { Loading Loading
core/java/android/view/SurfaceControlViewHost.java +22 −4 Original line number Original line Diff line number Diff line Loading @@ -24,6 +24,7 @@ import android.graphics.PixelFormat; import android.os.IBinder; import android.os.IBinder; import android.os.Parcel; import android.os.Parcel; import android.os.Parcelable; import android.os.Parcelable; import android.view.accessibility.IAccessibilityEmbeddedConnection; /** /** * Utility class for adding a View hierarchy to a {@link SurfaceControl}. The View hierarchy * Utility class for adding a View hierarchy to a {@link SurfaceControl}. The View hierarchy Loading @@ -40,6 +41,7 @@ public class SurfaceControlViewHost { private WindowlessWindowManager mWm; private WindowlessWindowManager mWm; private SurfaceControl mSurfaceControl; private SurfaceControl mSurfaceControl; private IAccessibilityEmbeddedConnection mAccessibilityEmbeddedConnection; /** /** * Package encapsulating a Surface hierarchy which contains interactive view * Package encapsulating a Surface hierarchy which contains interactive view Loading @@ -49,15 +51,18 @@ public class SurfaceControlViewHost { */ */ public static final class SurfacePackage implements Parcelable { public static final class SurfacePackage implements Parcelable { private final SurfaceControl mSurfaceControl; private final SurfaceControl mSurfaceControl; // TODO: Accessibility ID goes here private final IAccessibilityEmbeddedConnection mAccessibilityEmbeddedConnection; SurfacePackage(SurfaceControl sc) { SurfacePackage(SurfaceControl sc, IAccessibilityEmbeddedConnection connection) { mSurfaceControl = sc; mSurfaceControl = sc; mAccessibilityEmbeddedConnection = connection; } } private SurfacePackage(Parcel in) { private SurfacePackage(Parcel in) { mSurfaceControl = new SurfaceControl(); mSurfaceControl = new SurfaceControl(); mSurfaceControl.readFromParcel(in); mSurfaceControl.readFromParcel(in); mAccessibilityEmbeddedConnection = IAccessibilityEmbeddedConnection.Stub.asInterface( in.readStrongBinder()); } } /** /** Loading @@ -69,6 +74,16 @@ public class SurfaceControlViewHost { return mSurfaceControl; return mSurfaceControl; } } /** * Gets an accessibility embedded connection interface for this SurfaceControlViewHost. * * @return {@link IAccessibilityEmbeddedConnection} interface. * @hide */ public IAccessibilityEmbeddedConnection getAccessibilityEmbeddedConnection() { return mAccessibilityEmbeddedConnection; } @Override @Override public int describeContents() { public int describeContents() { return 0; return 0; Loading @@ -77,6 +92,7 @@ public class SurfaceControlViewHost { @Override @Override public void writeToParcel(@NonNull Parcel out, int flags) { public void writeToParcel(@NonNull Parcel out, int flags) { mSurfaceControl.writeToParcel(out, flags); mSurfaceControl.writeToParcel(out, flags); out.writeStrongBinder(mAccessibilityEmbeddedConnection.asBinder()); } } public static final @NonNull Creator<SurfacePackage> CREATOR public static final @NonNull Creator<SurfacePackage> CREATOR Loading @@ -95,6 +111,7 @@ public class SurfaceControlViewHost { @NonNull WindowlessWindowManager wwm) { @NonNull WindowlessWindowManager wwm) { mWm = wwm; mWm = wwm; mViewRoot = new ViewRootImpl(c, d, mWm); mViewRoot = new ViewRootImpl(c, d, mWm); mAccessibilityEmbeddedConnection = mViewRoot.getAccessibilityEmbeddedConnection(); } } /** /** Loading @@ -118,6 +135,7 @@ public class SurfaceControlViewHost { mWm = new WindowlessWindowManager(context.getResources().getConfiguration(), mWm = new WindowlessWindowManager(context.getResources().getConfiguration(), mSurfaceControl, hostToken); mSurfaceControl, hostToken); mViewRoot = new ViewRootImpl(context, display, mWm); mViewRoot = new ViewRootImpl(context, display, mWm); mAccessibilityEmbeddedConnection = mViewRoot.getAccessibilityEmbeddedConnection(); } } /** /** Loading @@ -128,8 +146,8 @@ public class SurfaceControlViewHost { * are linked. * are linked. */ */ public @Nullable SurfacePackage getSurfacePackage() { public @Nullable SurfacePackage getSurfacePackage() { if (mSurfaceControl != null) { if (mSurfaceControl != null && mAccessibilityEmbeddedConnection != null) { return new SurfacePackage(mSurfaceControl); return new SurfacePackage(mSurfaceControl, mAccessibilityEmbeddedConnection); } else { } else { return null; return null; } } Loading
core/java/android/view/SurfaceView.java +127 −16 Original line number Original line Diff line number Diff line Loading @@ -28,6 +28,7 @@ import android.content.res.CompatibilityInfo.Translator; import android.graphics.BlendMode; import android.graphics.BlendMode; import android.graphics.Canvas; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Color; import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.Paint; import android.graphics.PixelFormat; import android.graphics.PixelFormat; import android.graphics.PorterDuff; import android.graphics.PorterDuff; Loading @@ -38,12 +39,14 @@ import android.os.Build; import android.os.Handler; import android.os.Handler; import android.os.IBinder; import android.os.IBinder; import android.os.Looper; import android.os.Looper; import android.os.RemoteException; import android.os.SystemClock; import android.os.SystemClock; import android.util.AttributeSet; import android.util.AttributeSet; import android.util.Log; import android.util.Log; import android.view.SurfaceControl.Transaction; import android.view.SurfaceControl.Transaction; import android.view.SurfaceControlViewHost; import android.view.SurfaceControlViewHost; import android.view.accessibility.AccessibilityNodeInfo; import android.view.accessibility.AccessibilityNodeInfo; import android.view.accessibility.IAccessibilityEmbeddedConnection; import com.android.internal.view.SurfaceCallbackHelper; import com.android.internal.view.SurfaceCallbackHelper; Loading Loading @@ -203,8 +206,12 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall private SurfaceControl.Transaction mTmpTransaction = new SurfaceControl.Transaction(); private SurfaceControl.Transaction mTmpTransaction = new SurfaceControl.Transaction(); private int mParentSurfaceGenerationId; private int mParentSurfaceGenerationId; // The token of embedded windowless view hierarchy. private RemoteAccessibilityEmbeddedConnection mRemoteAccessibilityEmbeddedConnection; private IBinder mEmbeddedViewHierarchy; private final Matrix mScreenMatrixForEmbeddedHierarchy = new Matrix(); private final Matrix mTmpMatrix = new Matrix(); private final float[] mMatrixValues = new float[9]; SurfaceControlViewHost.SurfacePackage mSurfacePackage; SurfaceControlViewHost.SurfacePackage mSurfacePackage; public SurfaceView(Context context) { public SurfaceView(Context context) { Loading Loading @@ -923,6 +930,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall } } mTmpTransaction.apply(); mTmpTransaction.apply(); updateScreenMatrixForEmbeddedHierarchy(); if (sizeChanged || creating) { if (sizeChanged || creating) { redrawNeeded = true; redrawNeeded = true; Loading Loading @@ -1510,6 +1518,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall @Override @Override public void surfaceDestroyed() { public void surfaceDestroyed() { setWindowStopped(true); setWindowStopped(true); setRemoteAccessibilityEmbeddedConnection(null, null); } } /** /** Loading Loading @@ -1568,31 +1577,133 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall private void reparentSurfacePackage(SurfaceControl.Transaction t, private void reparentSurfacePackage(SurfaceControl.Transaction t, SurfaceControlViewHost.SurfacePackage p) { SurfaceControlViewHost.SurfacePackage p) { // TODO: Link accessibility IDs here. initEmbeddedHierarchyForAccessibility(p); final SurfaceControl sc = p.getSurfaceControl(); final SurfaceControl sc = p.getSurfaceControl(); t.reparent(sc, mSurfaceControl).show(sc); t.reparent(sc, mSurfaceControl).show(sc); } } /** * Add the token of embedded view hierarchy. Set {@code null} to clear the embedded view * hierarchy. * * @param token IBinder token. * @hide */ public void setEmbeddedViewHierarchy(IBinder token) { mEmbeddedViewHierarchy = token; } /** @hide */ /** @hide */ @Override @Override public void onInitializeAccessibilityNodeInfoInternal(AccessibilityNodeInfo info) { public void onInitializeAccessibilityNodeInfoInternal(AccessibilityNodeInfo info) { super.onInitializeAccessibilityNodeInfoInternal(info); super.onInitializeAccessibilityNodeInfoInternal(info); if (mEmbeddedViewHierarchy == null) { final RemoteAccessibilityEmbeddedConnection wrapper = getRemoteAccessibilityEmbeddedConnection(); if (wrapper == null) { return; return; } } // Add a leashed child when this SurfaceView embeds another view hierarchy. Getting this // Add a leashed child when this SurfaceView embeds another view hierarchy. Getting this // leashed child would return the root node in the embedded hierarchy // leashed child would return the root node in the embedded hierarchy info.addChild(mEmbeddedViewHierarchy); info.addChild(wrapper.getLeashToken()); } private void initEmbeddedHierarchyForAccessibility(SurfaceControlViewHost.SurfacePackage p) { final IAccessibilityEmbeddedConnection connection = p.getAccessibilityEmbeddedConnection(); final RemoteAccessibilityEmbeddedConnection wrapper = getRemoteAccessibilityEmbeddedConnection(); // Do nothing if package is embedding the same view hierarchy. if (wrapper != null && wrapper.getConnection().equals(connection)) { return; } // If this SurfaceView embeds a different view hierarchy, unlink the previous one first. setRemoteAccessibilityEmbeddedConnection(null, null); try { final IBinder leashToken = connection.associateEmbeddedHierarchy( getViewRootImpl().mLeashToken, getAccessibilityViewId()); setRemoteAccessibilityEmbeddedConnection(connection, leashToken); } catch (RemoteException e) { Log.d(TAG, "Error while associateEmbeddedHierarchy " + e); } updateScreenMatrixForEmbeddedHierarchy(); } private void setRemoteAccessibilityEmbeddedConnection( IAccessibilityEmbeddedConnection connection, IBinder leashToken) { try { if (mRemoteAccessibilityEmbeddedConnection != null) { mRemoteAccessibilityEmbeddedConnection.getConnection() .disassociateEmbeddedHierarchy(); mRemoteAccessibilityEmbeddedConnection.unlinkToDeath(); mRemoteAccessibilityEmbeddedConnection = null; } if (connection != null && leashToken != null) { mRemoteAccessibilityEmbeddedConnection = new RemoteAccessibilityEmbeddedConnection(connection, leashToken); mRemoteAccessibilityEmbeddedConnection.linkToDeath(); } } catch (RemoteException e) { Log.d(TAG, "Error while setRemoteEmbeddedConnection " + e); } } private RemoteAccessibilityEmbeddedConnection getRemoteAccessibilityEmbeddedConnection() { return mRemoteAccessibilityEmbeddedConnection; } private void updateScreenMatrixForEmbeddedHierarchy() { mTmpMatrix.reset(); mTmpMatrix.setTranslate(mScreenRect.left, mScreenRect.top); mTmpMatrix.postScale(mScreenRect.width() / (float) mSurfaceWidth, mScreenRect.height() / (float) mSurfaceHeight); // If the screen matrix is identity or doesn't change, do nothing. if (mTmpMatrix.isIdentity() || mTmpMatrix.equals(mScreenMatrixForEmbeddedHierarchy)) { return; } try { final RemoteAccessibilityEmbeddedConnection wrapper = getRemoteAccessibilityEmbeddedConnection(); if (wrapper == null) { return; } mTmpMatrix.getValues(mMatrixValues); wrapper.getConnection().setScreenMatrix(mMatrixValues); mScreenMatrixForEmbeddedHierarchy.set(mTmpMatrix); } catch (RemoteException e) { Log.d(TAG, "Error while setScreenMatrix " + e); } } /** * Wrapper of accessibility embedded connection for embedded view hierarchy. */ private final class RemoteAccessibilityEmbeddedConnection implements IBinder.DeathRecipient { private final IAccessibilityEmbeddedConnection mConnection; private final IBinder mLeashToken; RemoteAccessibilityEmbeddedConnection(IAccessibilityEmbeddedConnection connection, IBinder leashToken) { mConnection = connection; mLeashToken = leashToken; } IAccessibilityEmbeddedConnection getConnection() { return mConnection; } IBinder getLeashToken() { return mLeashToken; } void linkToDeath() throws RemoteException { mConnection.asBinder().linkToDeath(this, 0); } void unlinkToDeath() { mConnection.asBinder().unlinkToDeath(this, 0); } @Override public void binderDied() { unlinkToDeath(); runOnUiThread(() -> { if (mRemoteAccessibilityEmbeddedConnection == this) { mRemoteAccessibilityEmbeddedConnection = null; } }); } } } } }
core/java/android/view/ViewRootImpl.java +6 −5 Original line number Original line Diff line number Diff line Loading @@ -655,7 +655,7 @@ public final class ViewRootImpl implements ViewParent, private final GestureExclusionTracker mGestureExclusionTracker = new GestureExclusionTracker(); private final GestureExclusionTracker mGestureExclusionTracker = new GestureExclusionTracker(); private IAccessibilityEmbeddedConnection mEmbeddedConnection; private IAccessibilityEmbeddedConnection mAccessibilityEmbeddedConnection; static final class SystemUiVisibilityInfo { static final class SystemUiVisibilityInfo { int seq; int seq; Loading Loading @@ -9370,11 +9370,12 @@ public final class ViewRootImpl implements ViewParent, * Gets an accessibility embedded connection interface for this ViewRootImpl. * Gets an accessibility embedded connection interface for this ViewRootImpl. * @hide * @hide */ */ public IAccessibilityEmbeddedConnection getEmbeddedConnection() { public IAccessibilityEmbeddedConnection getAccessibilityEmbeddedConnection() { if (mEmbeddedConnection == null) { if (mAccessibilityEmbeddedConnection == null) { mEmbeddedConnection = new AccessibilityEmbeddedConnection(ViewRootImpl.this); mAccessibilityEmbeddedConnection = new AccessibilityEmbeddedConnection( ViewRootImpl.this); } } return mEmbeddedConnection; return mAccessibilityEmbeddedConnection; } } private class SendWindowContentChangedAccessibilityEvent implements Runnable { private class SendWindowContentChangedAccessibilityEvent implements Runnable { Loading