Merge changes I0333ab33,I7ae7b27f,If20185ce
* changes: SurfaceView Cleanup (3/n): Extract RemoteAccessibilityController SurfaceView Cleanup (2/n): Cleanup visible = mVisible SurfaceView Cleanup (1/n): Breakup updateSurface()
This commit is contained in:
168
core/java/android/view/RemoteAccessibilityController.java
Normal file
168
core/java/android/view/RemoteAccessibilityController.java
Normal file
@@ -0,0 +1,168 @@
|
||||
/*
|
||||
* Copyright (C) 2020 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.graphics.Matrix;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
import android.os.Looper;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Log;
|
||||
import android.view.accessibility.IAccessibilityEmbeddedConnection;
|
||||
|
||||
class RemoteAccessibilityController {
|
||||
private static final String TAG = "RemoteAccessibilityController";
|
||||
private int mHostId;
|
||||
private RemoteAccessibilityEmbeddedConnection mConnectionWrapper;
|
||||
private Matrix mScreenMatrixForEmbeddedHierarchy = new Matrix();
|
||||
private final float[] mMatrixValues = new float[9];
|
||||
private View mHostView;
|
||||
|
||||
RemoteAccessibilityController(View v) {
|
||||
mHostView = v;
|
||||
}
|
||||
|
||||
private void runOnUiThread(Runnable runnable) {
|
||||
final Handler h = mHostView.getHandler();
|
||||
if (h != null && h.getLooper() != Looper.myLooper()) {
|
||||
h.post(runnable);
|
||||
} else {
|
||||
runnable.run();
|
||||
}
|
||||
}
|
||||
|
||||
void assosciateHierarchy(IAccessibilityEmbeddedConnection connection,
|
||||
IBinder leashToken, int hostId) {
|
||||
mHostId = hostId;
|
||||
|
||||
try {
|
||||
leashToken = connection.associateEmbeddedHierarchy(
|
||||
leashToken, mHostId);
|
||||
setRemoteAccessibilityEmbeddedConnection(connection, leashToken);
|
||||
} catch (RemoteException e) {
|
||||
Log.d(TAG, "Error in associateEmbeddedHierarchy " + e);
|
||||
}
|
||||
}
|
||||
|
||||
void disassosciateHierarchy() {
|
||||
setRemoteAccessibilityEmbeddedConnection(null, null);
|
||||
}
|
||||
|
||||
boolean alreadyAssociated(IAccessibilityEmbeddedConnection connection) {
|
||||
if (mConnectionWrapper == null) {
|
||||
return false;
|
||||
}
|
||||
return mConnectionWrapper.mConnection.equals(connection);
|
||||
}
|
||||
|
||||
boolean connected() {
|
||||
return mConnectionWrapper != null;
|
||||
}
|
||||
|
||||
IBinder getLeashToken() {
|
||||
return mConnectionWrapper.getLeashToken();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 (mConnectionWrapper == this) {
|
||||
mConnectionWrapper = null;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void setRemoteAccessibilityEmbeddedConnection(
|
||||
IAccessibilityEmbeddedConnection connection, IBinder leashToken) {
|
||||
try {
|
||||
if (mConnectionWrapper != null) {
|
||||
mConnectionWrapper.getConnection()
|
||||
.disassociateEmbeddedHierarchy();
|
||||
mConnectionWrapper.unlinkToDeath();
|
||||
mConnectionWrapper = null;
|
||||
}
|
||||
if (connection != null && leashToken != null) {
|
||||
mConnectionWrapper =
|
||||
new RemoteAccessibilityEmbeddedConnection(connection, leashToken);
|
||||
mConnectionWrapper.linkToDeath();
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
Log.d(TAG, "Error while setRemoteEmbeddedConnection " + e);
|
||||
}
|
||||
}
|
||||
|
||||
private RemoteAccessibilityEmbeddedConnection getRemoteAccessibilityEmbeddedConnection() {
|
||||
return mConnectionWrapper;
|
||||
}
|
||||
|
||||
void setScreenMatrix(Matrix m) {
|
||||
// If the screen matrix is identity or doesn't change, do nothing.
|
||||
if (m.isIdentity() || m.equals(mScreenMatrixForEmbeddedHierarchy)) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
final RemoteAccessibilityEmbeddedConnection wrapper =
|
||||
getRemoteAccessibilityEmbeddedConnection();
|
||||
if (wrapper == null) {
|
||||
return;
|
||||
}
|
||||
m.getValues(mMatrixValues);
|
||||
wrapper.getConnection().setScreenMatrix(mMatrixValues);
|
||||
mScreenMatrixForEmbeddedHierarchy.set(m);
|
||||
} catch (RemoteException e) {
|
||||
Log.d(TAG, "Error while setScreenMatrix " + e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -227,9 +227,9 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
|
||||
private SurfaceControl.Transaction mTmpTransaction = new SurfaceControl.Transaction();
|
||||
private int mParentSurfaceGenerationId;
|
||||
|
||||
private RemoteAccessibilityEmbeddedConnection mRemoteAccessibilityEmbeddedConnection;
|
||||
private RemoteAccessibilityController mRemoteAccessibilityController =
|
||||
new RemoteAccessibilityController(this);
|
||||
|
||||
private final Matrix mScreenMatrixForEmbeddedHierarchy = new Matrix();
|
||||
private final Matrix mTmpMatrix = new Matrix();
|
||||
private final float[] mMatrixValues = new float[9];
|
||||
|
||||
@@ -927,6 +927,104 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
|
||||
}
|
||||
}
|
||||
|
||||
private boolean performSurfaceTransaction(ViewRootImpl viewRoot, Translator translator,
|
||||
boolean creating, boolean sizeChanged, boolean needBLASTSync) {
|
||||
boolean realSizeChanged = false;
|
||||
|
||||
mSurfaceLock.lock();
|
||||
try {
|
||||
mDrawingStopped = !mVisible;
|
||||
|
||||
if (DEBUG) Log.i(TAG, System.identityHashCode(this) + " "
|
||||
+ "Cur surface: " + mSurface);
|
||||
|
||||
// If we are creating the surface control or the parent surface has not
|
||||
// changed, then set relative z. Otherwise allow the parent
|
||||
// SurfaceChangedCallback to update the relative z. This is needed so that
|
||||
// we do not change the relative z before the server is ready to swap the
|
||||
// parent surface.
|
||||
if (creating || (mParentSurfaceGenerationId
|
||||
== viewRoot.mSurface.getGenerationId())) {
|
||||
updateRelativeZ(mTmpTransaction);
|
||||
}
|
||||
mParentSurfaceGenerationId = viewRoot.mSurface.getGenerationId();
|
||||
|
||||
if (mViewVisibility) {
|
||||
mTmpTransaction.show(mSurfaceControl);
|
||||
} else {
|
||||
mTmpTransaction.hide(mSurfaceControl);
|
||||
}
|
||||
|
||||
if (mSurfacePackage != null) {
|
||||
reparentSurfacePackage(mTmpTransaction, mSurfacePackage);
|
||||
}
|
||||
|
||||
updateBackgroundVisibility(mTmpTransaction);
|
||||
updateBackgroundColor(mTmpTransaction);
|
||||
if (mUseAlpha) {
|
||||
float alpha = getFixedAlpha();
|
||||
mTmpTransaction.setAlpha(mSurfaceControl, alpha);
|
||||
mSurfaceAlpha = alpha;
|
||||
}
|
||||
|
||||
// While creating the surface, we will set it's initial
|
||||
// geometry. Outside of that though, we should generally
|
||||
// leave it to the RenderThread.
|
||||
//
|
||||
// There is one more case when the buffer size changes we aren't yet
|
||||
// prepared to sync (as even following the transaction applying
|
||||
// we still need to latch a buffer).
|
||||
// b/28866173
|
||||
if (sizeChanged || creating || !mRtHandlingPositionUpdates) {
|
||||
onSetSurfacePositionAndScaleRT(mTmpTransaction, mSurfaceControl,
|
||||
mScreenRect.left, /*positionLeft*/
|
||||
mScreenRect.top /*positionTop*/ ,
|
||||
mScreenRect.width() / (float) mSurfaceWidth /*postScaleX*/,
|
||||
mScreenRect.height() / (float) mSurfaceHeight /*postScaleY*/);
|
||||
|
||||
// Set a window crop when creating the surface or changing its size to
|
||||
// crop the buffer to the surface size since the buffer producer may
|
||||
// use SCALING_MODE_SCALE and submit a larger size than the surface
|
||||
// size.
|
||||
if (mClipSurfaceToBounds && mClipBounds != null) {
|
||||
mTmpTransaction.setWindowCrop(mSurfaceControl, mClipBounds);
|
||||
} else {
|
||||
mTmpTransaction.setWindowCrop(mSurfaceControl, mSurfaceWidth,
|
||||
mSurfaceHeight);
|
||||
}
|
||||
} else if (needBLASTSync) {
|
||||
viewRoot.setUseBLASTSyncTransaction();
|
||||
}
|
||||
mTmpTransaction.setCornerRadius(mSurfaceControl, mCornerRadius);
|
||||
if (sizeChanged && !creating) {
|
||||
setBufferSize(mTmpTransaction);
|
||||
}
|
||||
|
||||
mTmpTransaction.apply();
|
||||
updateEmbeddedAccessibilityMatrix();
|
||||
|
||||
mSurfaceFrame.left = 0;
|
||||
mSurfaceFrame.top = 0;
|
||||
if (translator == null) {
|
||||
mSurfaceFrame.right = mSurfaceWidth;
|
||||
mSurfaceFrame.bottom = mSurfaceHeight;
|
||||
} else {
|
||||
float appInvertedScale = translator.applicationInvertedScale;
|
||||
mSurfaceFrame.right = (int) (mSurfaceWidth * appInvertedScale + 0.5f);
|
||||
mSurfaceFrame.bottom = (int) (mSurfaceHeight * appInvertedScale + 0.5f);
|
||||
}
|
||||
final int surfaceWidth = mSurfaceFrame.right;
|
||||
final int surfaceHeight = mSurfaceFrame.bottom;
|
||||
realSizeChanged = mLastSurfaceWidth != surfaceWidth
|
||||
|| mLastSurfaceHeight != surfaceHeight;
|
||||
mLastSurfaceWidth = surfaceWidth;
|
||||
mLastSurfaceHeight = surfaceHeight;
|
||||
} finally {
|
||||
mSurfaceLock.unlock();
|
||||
}
|
||||
return realSizeChanged;
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
protected void updateSurface() {
|
||||
if (!mHaveFrame) {
|
||||
@@ -965,7 +1063,6 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
|
||||
&& mRequestedVisible;
|
||||
final boolean sizeChanged = mSurfaceWidth != myWidth || mSurfaceHeight != myHeight;
|
||||
final boolean windowVisibleChanged = mWindowVisibility != mLastWindowVisibility;
|
||||
boolean redrawNeeded = false;
|
||||
getLocationInSurface(mLocation);
|
||||
final boolean positionChanged = mWindowSpaceLeft != mLocation[0]
|
||||
|| mWindowSpaceTop != mLocation[1];
|
||||
@@ -988,7 +1085,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
|
||||
+ " top=" + (mWindowSpaceTop != mLocation[1]));
|
||||
|
||||
try {
|
||||
final boolean visible = mVisible = mRequestedVisible;
|
||||
mVisible = mRequestedVisible;
|
||||
mWindowSpaceLeft = mLocation[0];
|
||||
mWindowSpaceTop = mLocation[1];
|
||||
mSurfaceWidth = myWidth;
|
||||
@@ -1014,119 +1111,26 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
|
||||
return;
|
||||
}
|
||||
|
||||
boolean realSizeChanged = false;
|
||||
|
||||
mSurfaceLock.lock();
|
||||
try {
|
||||
mDrawingStopped = !visible;
|
||||
|
||||
if (DEBUG) Log.i(TAG, System.identityHashCode(this) + " "
|
||||
+ "Cur surface: " + mSurface);
|
||||
|
||||
// If we are creating the surface control or the parent surface has not
|
||||
// changed, then set relative z. Otherwise allow the parent
|
||||
// SurfaceChangedCallback to update the relative z. This is needed so that
|
||||
// we do not change the relative z before the server is ready to swap the
|
||||
// parent surface.
|
||||
if (creating || (mParentSurfaceGenerationId
|
||||
== viewRoot.mSurface.getGenerationId())) {
|
||||
updateRelativeZ(mTmpTransaction);
|
||||
}
|
||||
mParentSurfaceGenerationId = viewRoot.mSurface.getGenerationId();
|
||||
|
||||
if (mViewVisibility) {
|
||||
mTmpTransaction.show(mSurfaceControl);
|
||||
} else {
|
||||
mTmpTransaction.hide(mSurfaceControl);
|
||||
}
|
||||
|
||||
if (mSurfacePackage != null) {
|
||||
reparentSurfacePackage(mTmpTransaction, mSurfacePackage);
|
||||
}
|
||||
|
||||
updateBackgroundVisibility(mTmpTransaction);
|
||||
updateBackgroundColor(mTmpTransaction);
|
||||
if (mUseAlpha) {
|
||||
mTmpTransaction.setAlpha(mSurfaceControl, alpha);
|
||||
mSurfaceAlpha = alpha;
|
||||
}
|
||||
|
||||
// While creating the surface, we will set it's initial
|
||||
// geometry. Outside of that though, we should generally
|
||||
// leave it to the RenderThread.
|
||||
//
|
||||
// There is one more case when the buffer size changes we aren't yet
|
||||
// prepared to sync (as even following the transaction applying
|
||||
// we still need to latch a buffer).
|
||||
// b/28866173
|
||||
if (sizeChanged || creating || !mRtHandlingPositionUpdates) {
|
||||
onSetSurfacePositionAndScaleRT(mTmpTransaction, mSurfaceControl,
|
||||
mScreenRect.left, /*positionLeft*/
|
||||
mScreenRect.top /*positionTop*/ ,
|
||||
mScreenRect.width() / (float) mSurfaceWidth /*postScaleX*/,
|
||||
mScreenRect.height() / (float) mSurfaceHeight /*postScaleY*/);
|
||||
|
||||
// Set a window crop when creating the surface or changing its size to
|
||||
// crop the buffer to the surface size since the buffer producer may
|
||||
// use SCALING_MODE_SCALE and submit a larger size than the surface
|
||||
// size.
|
||||
if (mClipSurfaceToBounds && mClipBounds != null) {
|
||||
mTmpTransaction.setWindowCrop(mSurfaceControl, mClipBounds);
|
||||
} else {
|
||||
mTmpTransaction.setWindowCrop(mSurfaceControl, mSurfaceWidth,
|
||||
mSurfaceHeight);
|
||||
}
|
||||
} else if ((layoutSizeChanged || positionChanged || visibleChanged) &&
|
||||
viewRoot.useBLAST()) {
|
||||
viewRoot.setUseBLASTSyncTransaction();
|
||||
}
|
||||
mTmpTransaction.setCornerRadius(mSurfaceControl, mCornerRadius);
|
||||
if (sizeChanged && !creating) {
|
||||
setBufferSize(mTmpTransaction);
|
||||
}
|
||||
|
||||
mTmpTransaction.apply();
|
||||
updateScreenMatrixForEmbeddedHierarchy();
|
||||
|
||||
if (sizeChanged || creating) {
|
||||
redrawNeeded = true;
|
||||
}
|
||||
|
||||
mSurfaceFrame.left = 0;
|
||||
mSurfaceFrame.top = 0;
|
||||
if (translator == null) {
|
||||
mSurfaceFrame.right = mSurfaceWidth;
|
||||
mSurfaceFrame.bottom = mSurfaceHeight;
|
||||
} else {
|
||||
float appInvertedScale = translator.applicationInvertedScale;
|
||||
mSurfaceFrame.right = (int) (mSurfaceWidth * appInvertedScale + 0.5f);
|
||||
mSurfaceFrame.bottom = (int) (mSurfaceHeight * appInvertedScale + 0.5f);
|
||||
}
|
||||
|
||||
final int surfaceWidth = mSurfaceFrame.right;
|
||||
final int surfaceHeight = mSurfaceFrame.bottom;
|
||||
realSizeChanged = mLastSurfaceWidth != surfaceWidth
|
||||
|| mLastSurfaceHeight != surfaceHeight;
|
||||
mLastSurfaceWidth = surfaceWidth;
|
||||
mLastSurfaceHeight = surfaceHeight;
|
||||
} finally {
|
||||
mSurfaceLock.unlock();
|
||||
}
|
||||
final boolean needBLASTSync =
|
||||
(layoutSizeChanged || positionChanged || visibleChanged) &&
|
||||
viewRoot.useBLAST();
|
||||
final boolean realSizeChanged = performSurfaceTransaction(viewRoot,
|
||||
translator, creating, sizeChanged, needBLASTSync);
|
||||
final boolean redrawNeeded = sizeChanged || creating ||
|
||||
(mVisible && !mDrawFinished);
|
||||
|
||||
try {
|
||||
redrawNeeded |= visible && !mDrawFinished;
|
||||
|
||||
SurfaceHolder.Callback[] callbacks = null;
|
||||
|
||||
final boolean surfaceChanged = creating;
|
||||
if (mSurfaceCreated && (surfaceChanged || (!visible && visibleChanged))) {
|
||||
if (mSurfaceCreated && (surfaceChanged || (!mVisible && visibleChanged))) {
|
||||
mSurfaceCreated = false;
|
||||
notifySurfaceDestroyed();
|
||||
}
|
||||
|
||||
copySurface(creating /* surfaceControlCreated */, sizeChanged);
|
||||
|
||||
if (visible && mSurface.isValid()) {
|
||||
if (mVisible && mSurface.isValid()) {
|
||||
if (!mSurfaceCreated && (surfaceChanged || visibleChanged)) {
|
||||
mSurfaceCreated = true;
|
||||
mIsCreating = true;
|
||||
@@ -1754,7 +1758,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
|
||||
@Override
|
||||
public void surfaceDestroyed() {
|
||||
setWindowStopped(true);
|
||||
setRemoteAccessibilityEmbeddedConnection(null, null);
|
||||
mRemoteAccessibilityController.disassosciateHierarchy();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1834,14 +1838,12 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
|
||||
@Override
|
||||
public void onInitializeAccessibilityNodeInfoInternal(AccessibilityNodeInfo info) {
|
||||
super.onInitializeAccessibilityNodeInfoInternal(info);
|
||||
final RemoteAccessibilityEmbeddedConnection wrapper =
|
||||
getRemoteAccessibilityEmbeddedConnection();
|
||||
if (wrapper == null) {
|
||||
if (!mRemoteAccessibilityController.connected()) {
|
||||
return;
|
||||
}
|
||||
// Add a leashed child when this SurfaceView embeds another view hierarchy. Getting this
|
||||
// leashed child would return the root node in the embedded hierarchy
|
||||
info.addChild(wrapper.getLeashToken());
|
||||
info.addChild(mRemoteAccessibilityController.getLeashToken());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1850,7 +1852,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
|
||||
// If developers explicitly set the important mode for it, don't change the mode.
|
||||
// Only change the mode to important when this SurfaceView isn't explicitly set and has
|
||||
// an embedded hierarchy.
|
||||
if (mRemoteAccessibilityEmbeddedConnection == null
|
||||
if (!mRemoteAccessibilityController.connected()
|
||||
|| mode != IMPORTANT_FOR_ACCESSIBILITY_AUTO) {
|
||||
return mode;
|
||||
}
|
||||
@@ -1859,74 +1861,13 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
|
||||
|
||||
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)) {
|
||||
if (mRemoteAccessibilityController.alreadyAssociated(connection)) {
|
||||
return;
|
||||
}
|
||||
mRemoteAccessibilityController.assosciateHierarchy(connection,
|
||||
getViewRootImpl().mLeashToken, getAccessibilityViewId());
|
||||
|
||||
// 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() {
|
||||
getBoundsOnScreen(mTmpRect);
|
||||
mTmpMatrix.reset();
|
||||
mTmpMatrix.setTranslate(mTmpRect.left, mTmpRect.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);
|
||||
}
|
||||
updateEmbeddedAccessibilityMatrix();
|
||||
}
|
||||
|
||||
private void notifySurfaceDestroyed() {
|
||||
@@ -1954,6 +1895,18 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
|
||||
}
|
||||
}
|
||||
|
||||
void updateEmbeddedAccessibilityMatrix() {
|
||||
if (!mRemoteAccessibilityController.connected()) {
|
||||
return;
|
||||
}
|
||||
getBoundsOnScreen(mTmpRect);
|
||||
mTmpMatrix.reset();
|
||||
mTmpMatrix.setTranslate(mTmpRect.left, mTmpRect.top);
|
||||
mTmpMatrix.postScale(mScreenRect.width() / (float) mSurfaceWidth,
|
||||
mScreenRect.height() / (float) mSurfaceHeight);
|
||||
mRemoteAccessibilityController.setScreenMatrix(mTmpMatrix);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onFocusChanged(boolean gainFocus, @FocusDirection int direction,
|
||||
@Nullable Rect previouslyFocusedRect) {
|
||||
@@ -1970,44 +1923,4 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
|
||||
+ "Exception requesting focus on embedded window", 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;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user